fix: 드로그 기본기3 Idle 복귀 루트모션 차단

- 기본기3 종료 후 Idle 복귀 블렌드 구간에서 수평 루트모션이 적용되지 않도록 차단

- SkillController가 Idle 복귀 블렌드 상태를 직접 노출하고 EnemyBase가 해당 구간만 별도로 처리하도록 정리

- 원인 추적용 Idle 복귀 좌표 로그는 제거하고 기능만 유지
This commit is contained in:
2026-04-21 16:54:30 +09:00
parent dadaa56511
commit 6d038f07ff
2 changed files with 56 additions and 1 deletions

View File

@@ -136,6 +136,8 @@ namespace Colosseum.Skills
private string currentClipDebugName = string.Empty;
private int currentClipStartFrame = -1;
private readonly List<Vector3> debugSkillStartPoints = new();
private bool isSuppressingIdleRecoveryHorizontalRootMotion = false;
private int idleRecoveryStateHash = 0;
public bool IsExecutingSkill => currentSkill != null;
@@ -143,6 +145,11 @@ namespace Colosseum.Skills
public bool UsesRootMotion => currentSkill != null && currentSkill.UseRootMotion;
public bool IgnoreRootMotionY => currentSkill != null && currentSkill.IgnoreRootMotionY;
/// <summary>
/// 스킬 종료 후 Idle 복귀 블렌드 중인지 반환합니다.
/// 이 구간에서는 Idle 클립의 수평 루트모션이 섞여 위치가 밀리지 않도록 별도 차단에 사용합니다.
/// </summary>
public bool IsSuppressingIdleRecoveryHorizontalRootMotion => isSuppressingIdleRecoveryHorizontalRootMotion;
/// <summary>
/// 현재 스킬의 루트 위치를 실제 이동에 반영해도 되는지 반환합니다.
/// 스킬 시작 직후 아직 Animator가 Skill 상태로 전이되지 않은 프레임에서는
/// 이전 상태의 루트 XZ가 누적되지 않도록 위치 적용을 잠시 차단합니다.
@@ -336,7 +343,13 @@ namespace Colosseum.Skills
private void Update()
{
if (currentSkill == null || animator == null) return;
if (animator == null)
return;
UpdateIdleRecoverySuppressionState();
if (currentSkill == null)
return;
UpdateCastTargetTracking();
@@ -1730,6 +1743,24 @@ namespace Colosseum.Skills
return Animator.StringToHash($"{BaseLayerName}.{SKILL_STATE_NAME}");
}
/// <summary>
/// Idle 복귀 블렌드가 끝나면 수평 루트모션 차단 플래그를 자동 해제합니다.
/// </summary>
private void UpdateIdleRecoverySuppressionState()
{
if (!isSuppressingIdleRecoveryHorizontalRootMotion || animator == null)
return;
if (animator.IsInTransition(0))
return;
if (idleRecoveryStateHash != 0 && animator.GetCurrentAnimatorStateInfo(0).fullPathHash == idleRecoveryStateHash)
{
isSuppressingIdleRecoveryHorizontalRootMotion = false;
idleRecoveryStateHash = 0;
}
}
/// <summary>
/// 현재 레이어가 실제 스킬 상태를 재생 중인지 확인합니다.
/// 스킬 시작 직후 한 프레임 동안 이전 상태 정보가 남아 조기 종료되는 것을 방지합니다.
@@ -1792,9 +1823,22 @@ namespace Colosseum.Skills
return;
animator.speed = 1f;
isSuppressingIdleRecoveryHorizontalRootMotion = false;
idleRecoveryStateHash = 0;
if (recoveryStateHash != 0 && animator.HasState(0, recoveryStateHash))
{
bool isIdleRecoveryState =
recoveryStateHash == ResolveBossIdleStateHash()
|| recoveryStateHash == Animator.StringToHash($"{BaseLayerName}.{IdleStateName}");
if (isIdleRecoveryState)
{
isSuppressingIdleRecoveryHorizontalRootMotion = true;
idleRecoveryStateHash = recoveryStateHash;
}
animator.CrossFadeInFixedTime(recoveryStateHash, GetSkillExitTransitionDuration(), 0, 0f);
}
}
}
}