Skip to content

Commit

Permalink
Update SimplePlayerAnimator.cs
Browse files Browse the repository at this point in the history
  • Loading branch information
glabute committed Jul 5, 2024
1 parent c1f66c4 commit e2d5de0
Showing 1 changed file with 61 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,20 @@ public class SimplePlayerAnimator : MonoBehaviour

SimplePlayerControllerBase m_Controller;
Vector3 m_PreviousPosition; // used if m_Controller == null or disabled
bool m_IsWalking;
bool m_IsRunning;
bool m_IsJumping;
bool m_LandTriggered;
bool m_JumpTriggered;

protected struct AnimationParams
{
public bool IsWalking;
public bool IsRunning;
public bool IsJumping;
public bool LandTriggered;
public bool JumpTriggered;
public Vector3 Direction; // normalized direction of motion
public float MotionScale; // scale factor for the animation speed
public float JumpScale; // scale factor for the jump animation
}
AnimationParams m_AnimationParams;

const float k_IdleThreshold = 0.2f;

public enum States { Idle, Walk, Run, Jump, RunJump }
Expand All @@ -49,11 +58,11 @@ public States State
{
get
{
if (m_IsJumping)
return m_IsRunning ? States.RunJump : States.Jump;
if (m_IsRunning)
if (m_AnimationParams.IsJumping)
return m_AnimationParams.IsRunning ? States.RunJump : States.Jump;
if (m_AnimationParams.IsRunning)
return States.Run;
return m_IsWalking ? States.Walk : States.Idle;
return m_AnimationParams.IsWalking ? States.Walk : States.Idle;
}
}

Expand All @@ -64,9 +73,9 @@ protected virtual void Start()
if (m_Controller != null)
{
// Install our callbacks to handle jump and animation based on velocity
m_Controller.StartJump += () => m_JumpTriggered = true;
m_Controller.EndJump += () => m_LandTriggered = true;
m_Controller.PostUpdate += (vel, jumpAnimationScale) => UpdateAnimation(vel, jumpAnimationScale);
m_Controller.StartJump += () => m_AnimationParams.JumpTriggered = true;
m_Controller.EndJump += () => m_AnimationParams.LandTriggered = true;
m_Controller.PostUpdate += (vel, jumpAnimationScale) => UpdateAnimationState(vel, jumpAnimationScale);
}
}

Expand All @@ -84,7 +93,7 @@ protected virtual void LateUpdate()
var pos = transform.position;
var vel = Quaternion.Inverse(transform.rotation) * (pos - m_PreviousPosition) / Time.deltaTime;
m_PreviousPosition = pos;
UpdateAnimation(vel, 1);
UpdateAnimationState(vel, 1);
}
}

Expand All @@ -95,53 +104,62 @@ protected virtual void LateUpdate()
/// <param name="vel">Player's velocity, in player-local coordinates.</param>
/// <param name="jumpAnimationScale">Scale factor to apply to the jump animation.
/// It can be used to slow down the jump animation for longer jumps.</param>
protected virtual void UpdateAnimation(Vector3 vel, float jumpAnimationScale)
void UpdateAnimationState(Vector3 vel, float jumpAnimationScale)
{
if (!TryGetComponent(out Animator animator))
{
Debug.LogError("SimplePlayerAnimator: An Animator component is required");
return;
}

vel.y = 0; // we don't consider vertical movement
var speed = vel.magnitude;

// Hysteresis reduction
bool isRunning = speed > NormalWalkSpeed * 2 + (m_IsRunning ? -0.15f : 0.15f);
bool isWalking = !isRunning && speed > k_IdleThreshold + (m_IsWalking ? -0.05f : 0.05f);
m_IsWalking = isWalking;
m_IsRunning = isRunning;
bool isRunning = speed > NormalWalkSpeed * 2 + (m_AnimationParams.IsRunning ? -0.15f : 0.15f);
bool isWalking = !isRunning && speed > k_IdleThreshold + (m_AnimationParams.IsWalking ? -0.05f : 0.05f);
m_AnimationParams.IsWalking = isWalking;
m_AnimationParams.IsRunning = isRunning;

// Set the normalized direction of motion and scale the animation speed to match motion speed
var dir = speed > k_IdleThreshold ? vel / speed : Vector3.zero;
var motionScale = isWalking ? speed / NormalWalkSpeed : 1;
m_AnimationParams.Direction = speed > k_IdleThreshold ? vel / speed : Vector3.zero;
m_AnimationParams.MotionScale = isWalking ? speed / NormalWalkSpeed : 1;
m_AnimationParams.JumpScale = JumpAnimationScale * jumpAnimationScale;

// We scale the sprint animation speed to loosely match the actual speed, but we cheat
// at the high end to avoid making the animation look ridiculous
if (isRunning)
motionScale = (speed < NormalSprintSpeed)
m_AnimationParams.MotionScale = (speed < NormalSprintSpeed)
? speed / NormalSprintSpeed
: Mathf.Min(MaxSprintScale, 1 + (speed - NormalSprintSpeed) / (3 * NormalSprintSpeed));

animator.SetFloat("DirX", dir.x);
animator.SetFloat("DirZ", dir.z);
animator.SetFloat("MotionScale", motionScale);
animator.SetBool("Walking", isWalking);
animator.SetBool("Running", isRunning);
animator.SetFloat("JumpScale", JumpAnimationScale * jumpAnimationScale);

if (m_JumpTriggered)
UpdateAnimation(m_AnimationParams);

if (m_AnimationParams.JumpTriggered)
m_AnimationParams.IsJumping = true;
if (m_AnimationParams.LandTriggered)
m_AnimationParams.IsJumping = false;

m_AnimationParams.JumpTriggered = false;
m_AnimationParams.LandTriggered = false;
}

/// <summary>
/// Update the animation based on the player's state.
/// Override this to interact appropriately with your animation controller.
/// </summary>
protected virtual void UpdateAnimation(AnimationParams animationParams)
{
if (!TryGetComponent(out Animator animator))
{
animator.SetTrigger("Jump");
m_JumpTriggered = false;
m_IsJumping = true;
Debug.LogError("SimplePlayerAnimator: An Animator component is required");
return;
}
if (m_LandTriggered)
{
animator.SetFloat("DirX", animationParams.Direction.x);
animator.SetFloat("DirZ", animationParams.Direction.z);
animator.SetFloat("MotionScale", animationParams.MotionScale);
animator.SetBool("Walking", animationParams.IsWalking);
animator.SetBool("Running", animationParams.IsRunning);
animator.SetFloat("JumpScale", animationParams.JumpScale);

if (m_AnimationParams.JumpTriggered)
animator.SetTrigger("Jump");
if (m_AnimationParams.LandTriggered)
animator.SetTrigger("Land");
m_LandTriggered = false;
m_IsJumping = false;
}
}
}
}

0 comments on commit e2d5de0

Please sign in to comment.