feat: 스킬별 행동 제한 정책 추가
- SkillData에 시전 중 이동, 점프, 추가 스킬 사용 제한 옵션을 추가 - PlayerActionState가 현재 스킬 정책을 읽어 행동 가능 여부를 계산하도록 변경 - 스킬 입력이 공통 행동 판정 규칙을 따르도록 정리
This commit is contained in:
@@ -50,6 +50,11 @@ namespace Colosseum.Player
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsCastingSkill => skillController != null && skillController.IsPlayingAnimation;
|
public bool IsCastingSkill => skillController != null && skillController.IsPlayingAnimation;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 현재 시전 중인 스킬
|
||||||
|
/// </summary>
|
||||||
|
public SkillData CurrentSkill => skillController != null ? skillController.CurrentSkill : null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 입력을 받아도 되는지 여부
|
/// 입력을 받아도 되는지 여부
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -58,22 +63,22 @@ namespace Colosseum.Player
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 플레이어가 직접 이동 입력을 사용할 수 있는지 여부
|
/// 플레이어가 직접 이동 입력을 사용할 수 있는지 여부
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool CanMove => CanReceiveInput && !IsStunned && !IsCastingSkill;
|
public bool CanMove => CanReceiveInput && !IsStunned && !BlocksMovementForCurrentSkill();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 점프 가능 여부
|
/// 점프 가능 여부
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool CanJump => CanMove;
|
public bool CanJump => CanReceiveInput && !IsStunned && !BlocksJumpForCurrentSkill();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 스킬 사용 가능 여부
|
/// 스킬 사용 가능 여부
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool CanUseSkills => CanReceiveInput && !IsStunned && !IsSilenced && !IsCastingSkill;
|
public bool CanUseSkills => CanReceiveInput && !IsStunned && !IsSilenced && !BlocksSkillUseForCurrentSkill();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 회피 사용 가능 여부
|
/// 회피 사용 가능 여부
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool CanEvade => CanUseSkills;
|
public bool CanEvade => CanReceiveInput && !IsStunned && !IsSilenced && !BlocksEvadeForCurrentSkill();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 현재 이동 속도 배율
|
/// 현재 이동 속도 배율
|
||||||
@@ -100,5 +105,37 @@ namespace Colosseum.Player
|
|||||||
if (spectator == null)
|
if (spectator == null)
|
||||||
spectator = GetComponentInChildren<PlayerSpectator>();
|
spectator = GetComponentInChildren<PlayerSpectator>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,6 +123,8 @@ namespace Colosseum.Player
|
|||||||
if (slotIndex < 0 || slotIndex >= skillSlots.Length)
|
if (slotIndex < 0 || slotIndex >= skillSlots.Length)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
bool isEvadeSlot = slotIndex == skillSlots.Length - 1;
|
||||||
|
|
||||||
SkillData skill = skillSlots[slotIndex];
|
SkillData skill = skillSlots[slotIndex];
|
||||||
if (skill == null)
|
if (skill == null)
|
||||||
{
|
{
|
||||||
@@ -131,8 +133,14 @@ namespace Colosseum.Player
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 사망 상태 체크
|
// 사망 상태 체크
|
||||||
if (actionState != null && !actionState.CanUseSkills)
|
if (actionState != null)
|
||||||
return;
|
{
|
||||||
|
if (isEvadeSlot && !actionState.CanEvade)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!isEvadeSlot && !actionState.CanUseSkills)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 로컬 체크 (빠른 피드백용)
|
// 로컬 체크 (빠른 피드백용)
|
||||||
if (skillController.IsExecutingSkill)
|
if (skillController.IsExecutingSkill)
|
||||||
@@ -168,13 +176,21 @@ namespace Colosseum.Player
|
|||||||
if (slotIndex < 0 || slotIndex >= skillSlots.Length)
|
if (slotIndex < 0 || slotIndex >= skillSlots.Length)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
bool isEvadeSlot = slotIndex == skillSlots.Length - 1;
|
||||||
|
|
||||||
SkillData skill = skillSlots[slotIndex];
|
SkillData skill = skillSlots[slotIndex];
|
||||||
if (skill == null) return;
|
if (skill == null) return;
|
||||||
|
|
||||||
// 서버에서 다시 검증
|
// 서버에서 다시 검증
|
||||||
// 사망 상태 체크
|
// 사망 상태 체크
|
||||||
if (actionState != null && !actionState.CanUseSkills)
|
if (actionState != null)
|
||||||
return;
|
{
|
||||||
|
if (isEvadeSlot && !actionState.CanEvade)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!isEvadeSlot && !actionState.CanUseSkills)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (skillController.IsExecutingSkill || skillController.IsOnCooldown(skill))
|
if (skillController.IsExecutingSkill || skillController.IsOnCooldown(skill))
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -31,6 +31,16 @@ namespace Colosseum.Skills
|
|||||||
[Tooltip("스킬 시전 시 대상 위치로 점프 이동 (UseRootMotion + IgnoreRootMotionY=false 필요)")]
|
[Tooltip("스킬 시전 시 대상 위치로 점프 이동 (UseRootMotion + IgnoreRootMotionY=false 필요)")]
|
||||||
[SerializeField] private bool jumpToTarget = 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("쿨타임 & 비용")]
|
[Header("쿨타임 & 비용")]
|
||||||
[Min(0f)] [SerializeField] private float cooldown = 1f;
|
[Min(0f)] [SerializeField] private float cooldown = 1f;
|
||||||
[Min(0f)] [SerializeField] private float manaCost = 0f;
|
[Min(0f)] [SerializeField] private float manaCost = 0f;
|
||||||
@@ -51,6 +61,10 @@ namespace Colosseum.Skills
|
|||||||
public bool UseRootMotion => useRootMotion;
|
public bool UseRootMotion => useRootMotion;
|
||||||
public bool IgnoreRootMotionY => ignoreRootMotionY;
|
public bool IgnoreRootMotionY => ignoreRootMotionY;
|
||||||
public bool JumpToTarget => jumpToTarget;
|
public bool JumpToTarget => jumpToTarget;
|
||||||
|
public bool BlockMovementWhileCasting => blockMovementWhileCasting;
|
||||||
|
public bool BlockJumpWhileCasting => blockJumpWhileCasting;
|
||||||
|
public bool BlockOtherSkillsWhileCasting => blockOtherSkillsWhileCasting;
|
||||||
|
public bool BlockEvadeWhileCasting => blockEvadeWhileCasting;
|
||||||
public IReadOnlyList<SkillEffect> Effects => effects;
|
public IReadOnlyList<SkillEffect> Effects => effects;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user