using BlueWater.Interfaces; using BlueWater.Utility; using Sirenix.OdinInspector; using UnityEngine; namespace BlueWater.Players.Combat { public class CombatStatus : MonoBehaviour, IStunnable, ISlowable { // Variables #region Variables // Components [SerializeField] private SpriteRenderer _spriteRenderer; private IPhysicMovable _physicMovable; private IDashable _dashable; private IComboAttackable _comboAttackable; private ISkillHandler _skillHandler; // Stun [Title("기절 효과")] [SerializeField] private ParticleSystem _stunParticle; public bool IsStunEnabled { get; private set; } = true; public bool IsStunned { get; private set; } private Coroutine _stunCoolDownCoroutine; // Slow [Title("슬로우 효과")] [SerializeField] private Color _slowEffectColor; public bool IsSlowMoveEnabled { get; private set; } = true; public bool IsSlowedMoveSpeed { get; private set; } private Coroutine _slowMoveSpeedCoolDownCoroutine; // Hashes private static readonly int _colorHash = Shader.PropertyToID("_Color"); #endregion // Unity events #region Unity events private void Awake() { InitializeComponents(); } #endregion // Initialize methods #region Initialize methods [Button("컴포넌트 초기화")] private void InitializeComponents() { _spriteRenderer = GetComponentInChildren(); _physicMovable = GetComponent(); _dashable = GetComponent(); _comboAttackable = GetComponent(); _skillHandler = GetComponent(); } #endregion // Methods #region Methods // Stun public bool CanStun() { if (!IsStunEnabled) return false; var isDashing = _dashable?.IsDashing ?? false; var isActivatingSkill = _skillHandler?.IsActivatingSkill ?? false; return !isDashing && !isActivatingSkill; } public void Stun(float duration) { _stunParticle.Play(); IsStunned = true; Utils.StartUniqueCoroutine(this, ref _stunCoolDownCoroutine, Utils.CoolDownCoroutine(duration, EndStun)); } public void TryStun(float duration) { if (!CanStun()) return; Stun(duration); } public void EndStun() { IsStunned = false; _stunParticle.Stop(); _stunParticle.Clear(); Utils.EndUniqueCoroutine(this, ref _stunCoolDownCoroutine); } // Slow public bool CanSlowMove() { if (!IsSlowMoveEnabled) return false; var isDashing = _dashable?.IsDashing ?? false; var isActivatingSkill = _skillHandler?.IsActivatingSkill ?? false; return !isDashing && !isActivatingSkill; } public void SlowMoveSpeed(float duration, float moveSpeedCoefficient) { _spriteRenderer.material.SetColor(_colorHash, _slowEffectColor); _physicMovable?.SetMoveSpeedCoefficient(moveSpeedCoefficient); IsSlowedMoveSpeed = true; Utils.StartUniqueCoroutine(this, ref _slowMoveSpeedCoolDownCoroutine, Utils.CoolDownCoroutine(duration, EndSlowMoveSpeed)); } public void TrySlowMoveSpeed(float duration, float moveSpeedCoefficient) { if (!CanSlowMove()) return; SlowMoveSpeed(duration, moveSpeedCoefficient); } public void EndSlowMoveSpeed() { IsSlowedMoveSpeed = false; _spriteRenderer.material.SetColor(_colorHash, Color.white); _physicMovable?.ResetMoveSpeedCoefficient(); Utils.EndUniqueCoroutine(this, ref _slowMoveSpeedCoolDownCoroutine); } #endregion } }