Add per-pose fall animation state and clip
Play a dedicated falling animation when the player is airborne and descending past a scale-aware velocity threshold. - PlayerCharacterController: new IsFalling state + Fall Animation Speed threshold (true only when !grounded && !wallClimbing && descending, scaled via CapsuleScale); explicitly false during wall/ceiling climb. - PlayerPose: per-pose Fall Clip + Fall Clip Speed (mirrors walk/run). - PlayerPoseController: select the fall clip while falling, fall back to the idle clip when a pose has none (no regression). - Author content: Paintman-Fall.anim assigned to Pose_Idle; UMotion project, Player prefab and scene authoring. - Docs: check off the fall animation in GAME_DESIGN.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
fc73e26da1
commit
3b26f2e622
10 files changed
+11515
-101
No files matched your search
@@ -71,6 +71,10 @@ public partial class PlayerCharacterController : MonoBehaviour
|
||||
[Tooltip("Small downward velocity kept while grounded for reliable ground contact.")]
|
||||
public float groundedStickVelocity = -2f;
|
||||
|
||||
[Tooltip("Downward speed (units/second) past which the player counts as falling, for the fall " +
|
||||
"animation. Only while airborne (not grounded, not wall-climbing). Scales with player size.")]
|
||||
public float fallAnimationSpeed = 4f;
|
||||
|
||||
[Header("Slope Sliding")]
|
||||
[Tooltip("Slide down surfaces steeper than the CharacterController's Slope Limit instead of balancing on them.")]
|
||||
public bool slideDownSteepSlopes = true;
|
||||
@@ -177,6 +181,13 @@ public partial class PlayerCharacterController : MonoBehaviour
|
||||
/// </summary>
|
||||
public bool IsMovingOnGround => _movingOnGround;
|
||||
|
||||
/// <summary>
|
||||
/// True while airborne and descending faster than <see cref="fallAnimationSpeed"/> (scaled by player
|
||||
/// size): not grounded and not wall-climbing. Rising after a jump, standing, moving on the ground, and
|
||||
/// wall/ceiling states all read false. Exposed so the pose system can pick its fall clip.
|
||||
/// </summary>
|
||||
public bool IsFalling => _isFalling;
|
||||
|
||||
/// <summary>
|
||||
/// Set by <see cref="PlayerPoseController"/> while a pose Playable graph owns the Animator output.
|
||||
/// While set, the run-bool is not poked: it would be moot (the graph overrides it) and Unity would
|
||||
@@ -211,6 +222,7 @@ public partial class PlayerCharacterController : MonoBehaviour
|
||||
private bool _sprinting; // sprint key state this frame (exposed via IsSprinting)
|
||||
private bool _isIdle; // snapshot: player essentially still this frame (exposed via IsIdle)
|
||||
private bool _movingOnGround; // snapshot: grounded & moving above the run threshold (exposed via IsMovingOnGround)
|
||||
private bool _isFalling; // snapshot: airborne & descending past the fall threshold (exposed via IsFalling)
|
||||
private float _groundOffset; // signed vertical mesh raise from the ground mouse pose-adjust (+ up / - down); folded into SetMeshLean
|
||||
|
||||
// Ground contact normal from the latest Move (for slope sliding).
|
||||
@@ -367,6 +379,7 @@ public partial class PlayerCharacterController : MonoBehaviour
|
||||
_horizontalVelocity = Vector3.zero; // drop ground momentum so resuming starts from rest
|
||||
_isIdle = ControlEnabled && (h * h + v * v) <= 1e-4f; // attached & no climb input = holding a pose
|
||||
_movingOnGround = false; // on a wall/ceiling, never ground locomotion
|
||||
_isFalling = false; // attached to a surface, not falling
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -453,6 +466,9 @@ public partial class PlayerCharacterController : MonoBehaviour
|
||||
bool movingOnGround = _controller.isGrounded && horizontalVel.sqrMagnitude > RunningSpeedThresholdSqr;
|
||||
_movingOnGround = movingOnGround;
|
||||
_isIdle = ControlEnabled && _controller.isGrounded && !movingOnGround; // standing still on the floor
|
||||
// Falling: airborne and descending past the threshold (wall-climb already returned above, so
|
||||
// not-grounded here means free in the air). Scaled by player size like gravity/jump.
|
||||
_isFalling = !_controller.isGrounded && _verticalVelocity < -fallAnimationSpeed * CapsuleScale;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in new issue
Block a user