diff --git a/Assets/_Game/Scripts/Player/PlayerActionState.cs b/Assets/_Game/Scripts/Player/PlayerActionState.cs index adab2451..803cc40f 100644 --- a/Assets/_Game/Scripts/Player/PlayerActionState.cs +++ b/Assets/_Game/Scripts/Player/PlayerActionState.cs @@ -50,6 +50,11 @@ namespace Colosseum.Player /// public bool IsCastingSkill => skillController != null && skillController.IsPlayingAnimation; + /// + /// 현재 시전 중인 스킬 + /// + public SkillData CurrentSkill => skillController != null ? skillController.CurrentSkill : null; + /// /// 입력을 받아도 되는지 여부 /// @@ -58,22 +63,22 @@ namespace Colosseum.Player /// /// 플레이어가 직접 이동 입력을 사용할 수 있는지 여부 /// - public bool CanMove => CanReceiveInput && !IsStunned && !IsCastingSkill; + public bool CanMove => CanReceiveInput && !IsStunned && !BlocksMovementForCurrentSkill(); /// /// 점프 가능 여부 /// - public bool CanJump => CanMove; + public bool CanJump => CanReceiveInput && !IsStunned && !BlocksJumpForCurrentSkill(); /// /// 스킬 사용 가능 여부 /// - public bool CanUseSkills => CanReceiveInput && !IsStunned && !IsSilenced && !IsCastingSkill; + public bool CanUseSkills => CanReceiveInput && !IsStunned && !IsSilenced && !BlocksSkillUseForCurrentSkill(); /// /// 회피 사용 가능 여부 /// - public bool CanEvade => CanUseSkills; + public bool CanEvade => CanReceiveInput && !IsStunned && !IsSilenced && !BlocksEvadeForCurrentSkill(); /// /// 현재 이동 속도 배율 @@ -100,5 +105,37 @@ namespace Colosseum.Player if (spectator == null) spectator = GetComponentInChildren(); } + + private bool BlocksMovementForCurrentSkill() + { + if (!IsCastingSkill) + return false; + + return CurrentSkill == null || CurrentSkill.BlockMovementWhileCasting; + } + + private bool BlocksJumpForCurrentSkill() + { + if (!IsCastingSkill) + return false; + + return CurrentSkill == null || CurrentSkill.BlockJumpWhileCasting; + } + + private bool BlocksSkillUseForCurrentSkill() + { + if (!IsCastingSkill) + return false; + + return CurrentSkill == null || CurrentSkill.BlockOtherSkillsWhileCasting; + } + + private bool BlocksEvadeForCurrentSkill() + { + if (!IsCastingSkill) + return false; + + return CurrentSkill == null || CurrentSkill.BlockEvadeWhileCasting; + } } } diff --git a/Assets/_Game/Scripts/Player/PlayerSkillInput.cs b/Assets/_Game/Scripts/Player/PlayerSkillInput.cs index 7c84a444..28a625cb 100644 --- a/Assets/_Game/Scripts/Player/PlayerSkillInput.cs +++ b/Assets/_Game/Scripts/Player/PlayerSkillInput.cs @@ -123,6 +123,8 @@ namespace Colosseum.Player if (slotIndex < 0 || slotIndex >= skillSlots.Length) return; + bool isEvadeSlot = slotIndex == skillSlots.Length - 1; + SkillData skill = skillSlots[slotIndex]; if (skill == null) { @@ -131,8 +133,14 @@ namespace Colosseum.Player } // 사망 상태 체크 - if (actionState != null && !actionState.CanUseSkills) - return; + if (actionState != null) + { + if (isEvadeSlot && !actionState.CanEvade) + return; + + if (!isEvadeSlot && !actionState.CanUseSkills) + return; + } // 로컬 체크 (빠른 피드백용) if (skillController.IsExecutingSkill) @@ -168,13 +176,21 @@ namespace Colosseum.Player if (slotIndex < 0 || slotIndex >= skillSlots.Length) return; + bool isEvadeSlot = slotIndex == skillSlots.Length - 1; + SkillData skill = skillSlots[slotIndex]; if (skill == null) return; // 서버에서 다시 검증 // 사망 상태 체크 - if (actionState != null && !actionState.CanUseSkills) - return; + if (actionState != null) + { + if (isEvadeSlot && !actionState.CanEvade) + return; + + if (!isEvadeSlot && !actionState.CanUseSkills) + return; + } if (skillController.IsExecutingSkill || skillController.IsOnCooldown(skill)) return; diff --git a/Assets/_Game/Scripts/Skills/SkillData.cs b/Assets/_Game/Scripts/Skills/SkillData.cs index ffb200d7..7857f12a 100644 --- a/Assets/_Game/Scripts/Skills/SkillData.cs +++ b/Assets/_Game/Scripts/Skills/SkillData.cs @@ -31,6 +31,16 @@ namespace Colosseum.Skills [Tooltip("스킬 시전 시 대상 위치로 점프 이동 (UseRootMotion + IgnoreRootMotionY=false 필요)")] [SerializeField] private bool jumpToTarget = false; + [Header("행동 제한")] + [Tooltip("시전 중 이동 입력 차단 여부")] + [SerializeField] private bool blockMovementWhileCasting = true; + [Tooltip("시전 중 점프 입력 차단 여부")] + [SerializeField] private bool blockJumpWhileCasting = true; + [Tooltip("시전 중 다른 스킬 입력 차단 여부")] + [SerializeField] private bool blockOtherSkillsWhileCasting = true; + [Tooltip("시전 중 회피 입력 차단 여부")] + [SerializeField] private bool blockEvadeWhileCasting = true; + [Header("쿨타임 & 비용")] [Min(0f)] [SerializeField] private float cooldown = 1f; [Min(0f)] [SerializeField] private float manaCost = 0f; @@ -51,6 +61,10 @@ namespace Colosseum.Skills public bool UseRootMotion => useRootMotion; public bool IgnoreRootMotionY => ignoreRootMotionY; public bool JumpToTarget => jumpToTarget; + public bool BlockMovementWhileCasting => blockMovementWhileCasting; + public bool BlockJumpWhileCasting => blockJumpWhileCasting; + public bool BlockOtherSkillsWhileCasting => blockOtherSkillsWhileCasting; + public bool BlockEvadeWhileCasting => blockEvadeWhileCasting; public IReadOnlyList Effects => effects; } }