스킬 시스템에 루트 모션 지원 추가

- SkillData: useRootMotion, ignoreRootMotionY 설정 추가
- SkillController: 루트 모션 관련 프로퍼티 노출
- PlayerMovement: OnAnimatorMove로 스킬 애니메이션의 이동/회전 데이터 적용
- Y축 무시 옵션으로 중력 및 충돌 처리 유지 가능

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-10 12:34:37 +09:00
parent eff23471d7
commit 680aacf580
4 changed files with 94 additions and 3 deletions

View File

@@ -22,6 +22,7 @@ namespace Colosseum.Player
[Header("References")]
[SerializeField] private SkillController skillController;
[SerializeField] private Animator animator;
private CharacterController characterController;
private Vector3 velocity;
@@ -64,6 +65,12 @@ namespace Colosseum.Player
skillController = GetComponent<SkillController>();
}
// Animator 참조
if (animator == null)
{
animator = GetComponentInChildren<Animator>();
}
// 스폰 포인트에서 위치 설정
SetSpawnPosition();
@@ -174,11 +181,14 @@ namespace Colosseum.Player
{
if (characterController == null) return;
// 스킬 애니메이션 재생 중에는 이동 불가
// 스킬 애니메이션 재생 중에는 이동 불가 (루트 모션은 OnAnimatorMove에서 처리)
if (skillController != null && skillController.IsPlayingAnimation)
{
// 중력만 적용
characterController.Move(velocity * Time.deltaTime);
// 루트 모션을 사용하지 않는 경우 중력만 적용
if (!skillController.UsesRootMotion)
{
characterController.Move(velocity * Time.deltaTime);
}
return;
}
@@ -248,5 +258,45 @@ namespace Colosseum.Player
return cameraRight * direction.x + cameraForward * direction.z;
}
/// <summary>
/// 루트 모션 처리. 스킬 애니메이션 중에 애니메이션의 이동/회전 데이터를 적용합니다.
/// </summary>
private void OnAnimatorMove()
{
if (!IsOwner) return;
if (animator == null || characterController == null) return;
if (skillController == null || !skillController.IsPlayingAnimation) return;
if (!skillController.UsesRootMotion) return;
// 루트 모션 이동 적용
Vector3 deltaPosition = animator.deltaPosition;
// Y축 무시 설정 시 중력 유지
if (skillController.IgnoreRootMotionY)
{
deltaPosition.y = 0f;
characterController.Move(deltaPosition + velocity * Time.deltaTime);
}
else
{
characterController.Move(deltaPosition);
}
// 루트 모션 회전 적용
if (animator.deltaRotation != Quaternion.identity)
{
transform.rotation *= animator.deltaRotation;
}
// 착지 체크
if (!wasGrounded && characterController.isGrounded && isJumping)
{
OnJumpEnd();
}
wasGrounded = characterController.isGrounded;
}
}
}