Player partial implementing animation updates for a skinned body model. It computes movement parameters from velocity and rotation, sets animgraph variables on a SkinnedModelRenderer, updates look direction, and applies a custom movement-state parameter and tint.
using System;
using Sandbox;
namespace BrickJam;
public sealed partial class Player
{
/// <summary>
/// The skinned body model. Set on the player prefab. Replaces the legacy
/// <c>AnimatedEntity</c> self-model.
/// </summary>
[Property] public SkinnedModelRenderer Body { get; set; }
private void UpdateAnimation()
{
if ( !Body.IsValid() )
return;
// Citizen animgraph parameters, set directly on the renderer (mirrors what
// CitizenAnimationHelper.WithVelocity does, without depending on the base addon's
// Sandbox.Citizen namespace which isn't available here).
var velocity = Velocity;
var rotation = Body.WorldRotation;
var forward = rotation.Forward.Dot( velocity );
var sideward = rotation.Right.Dot( velocity );
var moveAngle = MathF.Atan2( sideward, forward ).RadianToDegree().NormalizeDegrees();
Body.Set( "move_direction", moveAngle );
Body.Set( "move_speed", velocity.Length );
Body.Set( "move_groundspeed", velocity.WithZ( 0 ).Length );
Body.Set( "move_y", sideward );
Body.Set( "move_x", forward );
Body.Set( "move_z", velocity.z );
Body.Set( "duck", IsCrouching ? 1f : 0f );
Body.Set( "b_grounded", IsOnGround );
Body.SetLookDirection( "aim_eyes", InputRotation.Forward );
// Custom parameters specific to this game's citizen animgraph.
Body.Set( "special_movement_states", IsStunned ? 1 : (IsTripping ? 2 : (IsSlipping ? 3 : 0)) );
Body.Set( "speed_scale", velocity.WithZ( 0 ).Length / 150f );
ApplyMaskTint();
}
}