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;
}
}