2026-05-18 이동 애니메이션, 점프 애니메이션

This commit is contained in:
2026-05-18 15:24:47 +09:00
parent 271991d32f
commit 239c66af5b
10 changed files with 88 additions and 28 deletions

Binary file not shown.

View File

@@ -6,6 +6,7 @@ public enum ComboInputType
{ {
Punch, Punch,
Kick, Kick,
Grab,
Motion Motion
} }

View File

@@ -6,7 +6,20 @@ public class PlayerController : MonoBehaviour
{ {
[Header("Movement")] [Header("Movement")]
[SerializeField] private float _moveSpeed = 5f; [SerializeField] private float _moveSpeed = 5f;
[SerializeField] private string _walkAnimationState = "Walk";
private float _moveInputX = 0f; private float _moveInputX = 0f;
private string _activeBaseState;
private bool _isInActionAnimation;
[Header("Jump Animation")]
[SerializeField] private string _jumpRiseAnimationState = "JumpRise";
[SerializeField] private string _jumpMidAnimationState = "JumpMid";
[SerializeField] private string _jumpFallAnimationState = "JumpFall";
[SerializeField] private string _landAnimationState = "Land";
[SerializeField] private float _jumpMidThreshold = 2f;
[SerializeField] private float _landAnimationDuration = 0.15f;
private bool _wasGroundedLastFrame = true;
private float _landTimer;
[Header("Jump")] [Header("Jump")]
[SerializeField] private float _jumpForce = 8f; [SerializeField] private float _jumpForce = 8f;
@@ -153,6 +166,8 @@ private void FixedUpdate()
// 플레이어와 적 몸체는 물리 충돌하지 않고, 땅/벽만 캐스트로 이동을 막는다. // 플레이어와 적 몸체는 물리 충돌하지 않고, 땅/벽만 캐스트로 이동을 막는다.
ClampVelocityToGround(); ClampVelocityToGround();
UpdateLocomotionAnimation();
} }
private void ExecuteBufferedInputIfReady() private void ExecuteBufferedInputIfReady()
@@ -203,10 +218,11 @@ private void OnJumpInput()
private void OnPunchInput() => HandleComboInput(ComboInputType.Punch); private void OnPunchInput() => HandleComboInput(ComboInputType.Punch);
private void OnKickInput() => HandleComboInput(ComboInputType.Kick); private void OnKickInput() => HandleComboInput(ComboInputType.Kick);
private void OnGrabSmashInput() => HandleComboInput(ComboInputType.Grab);
private void OnDashInput() => ExecuteMotionNode(_dashRootNode); private void OnDashInput() => ExecuteMotionNode(_dashRootNode);
private void OnRollInput() => ExecuteMotionNode(_rollRootNode); private void OnRollInput() => ExecuteMotionNode(_rollRootNode);
private void OnBackDashInput() => ExecuteMotionNode(_backDashRootNode); private void OnBackDashInput() => ExecuteMotionNode(_backDashRootNode);
private void OnGrabSmashInput() => ExecuteAttackNode(_grabSmashRootNode);
private void HandleComboInput(ComboInputType input) private void HandleComboInput(ComboInputType input)
{ {
@@ -250,6 +266,7 @@ private void ExecuteComboInput(ComboInputType input)
{ {
ComboInputType.Punch => _punchRootNode, ComboInputType.Punch => _punchRootNode,
ComboInputType.Kick => _kickRootNode, ComboInputType.Kick => _kickRootNode,
ComboInputType.Grab => _grabSmashRootNode,
_ => null _ => null
}; };
if (root == null || root.Action == null) return; if (root == null || root.Action == null) return;
@@ -269,16 +286,6 @@ private void ExecuteMotionNode(ComboNode root)
_comboWindowTimer = root.ComboWindow; _comboWindowTimer = root.ComboWindow;
} }
private void ExecuteAttackNode(ComboNode root)
{
if (root == null || root.Action == null) return;
if (_attackCooldownTimer > 0f) return;
PerformAttack(root.Action);
_currentNode = root;
_comboWindowTimer = root.ComboWindow;
}
private void UpdateMotionCooldowns() private void UpdateMotionCooldowns()
{ {
if (_motionCooldownTimers.Count == 0) return; if (_motionCooldownTimers.Count == 0) return;
@@ -638,8 +645,58 @@ private void PlayIdleAnimation()
CancelAndDispose(ref _animationSpeedCts); CancelAndDispose(ref _animationSpeedCts);
CancelAndDispose(ref _actionVelocityCts); CancelAndDispose(ref _actionVelocityCts);
_anim.speed = 1f; _anim.speed = 1f;
if (!string.IsNullOrEmpty(_idleAnimationState)) _isInActionAnimation = false;
_anim.Play(_idleAnimationState); _activeBaseState = null;
PlayLocomotionState();
}
private void PlayLocomotionState()
{
if (_anim == null) return;
string desired = ChooseLocomotionState();
if (string.IsNullOrEmpty(desired)) return;
if (desired == _activeBaseState) return;
_anim.Play(desired);
_activeBaseState = desired;
}
private string ChooseLocomotionState()
{
if (_landTimer > 0f && !string.IsNullOrEmpty(_landAnimationState))
return _landAnimationState;
float vy = _rb.linearVelocity.y;
bool inAir = !_isGrounded || vy > _jumpMidThreshold;
if (inAir)
{
if (vy > _jumpMidThreshold && !string.IsNullOrEmpty(_jumpRiseAnimationState))
return _jumpRiseAnimationState;
if (vy < -_jumpMidThreshold && !string.IsNullOrEmpty(_jumpFallAnimationState))
return _jumpFallAnimationState;
if (!string.IsNullOrEmpty(_jumpMidAnimationState))
return _jumpMidAnimationState;
}
if (_moveInputX != 0f && !string.IsNullOrEmpty(_walkAnimationState))
return _walkAnimationState;
return _idleAnimationState;
}
private void UpdateLocomotionAnimation()
{
if (_isInActionAnimation) return;
if (_isGrounded && !_wasGroundedLastFrame && !string.IsNullOrEmpty(_landAnimationState))
_landTimer = _landAnimationDuration;
_wasGroundedLastFrame = _isGrounded;
if (_landTimer > 0f)
_landTimer -= Time.fixedDeltaTime;
PlayLocomotionState();
} }
private void PlayActionAnimation(ActionData data) private void PlayActionAnimation(ActionData data)
@@ -654,6 +711,8 @@ private void PlayActionAnimation(ActionData data)
{ {
_anim.Play(data.AnimationState); _anim.Play(data.AnimationState);
_anim.Update(0f); _anim.Update(0f);
_isInActionAnimation = true;
_activeBaseState = null;
} }
ApplyAnimationSpeedCurve(data, _animationSpeedCts.Token); ApplyAnimationSpeedCurve(data, _animationSpeedCts.Token);

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.