S&box Wiki

Revision Difference

Player_Animator#546580

<cat>Code.Player</cat> <title>Player Animator</title> # What is a Player Animator The Animator is responsible for maintaining your AnimGraph with up to date information. You can also set the position and rotation of your player in the Animator. # Example ``` public class StandardPlayerAnimator : PlayerAnimator⤶ { public override void Tick() {⤶ DoRotation(); DoWalk(); //⤶ // Let the animation graph know some shit⤶ //⤶ SetParam( "b_grounded", GroundEntity != null ); //⤶ // Look in the direction what the player's input is facing⤶ //⤶ SetLookAt( "lookat_pos", Player.EyePos + Input.Rot.Forward * 1000 );⤶ } ⤶ public virtual void DoRotation() { //⤶ // Our ideal player model rotation is the way we're facing⤶ //⤶ var idealRotation = Rotation.LookAt( Input.Rot.Forward.WithZ( 0 ), Vector3.Up ); //⤶ // If we're moving, rotate to our ideal rotation⤶ //⤶ Rot = Rotation.Slerp( Rot, idealRotation, WishVelocity.Length * Time.Delta * 0.01f ); //⤶ // Clamp the foot rotation to within 120 degrees of the ideal rotation⤶ //⤶ Rot = Rot.Clamp( idealRotation, 120 );⤶ } ⤶ void DoWalk() { //⤶ // These tweak the animation speeds to something we feel is right, // so the foot speed matches the floor speed. Your art should probably⤶ // do this - but that ain't how we roll⤶ //⤶ SetParam( "walkspeed_scale", 2.0f / 190.0f ); SetParam( "runspeed_scale", 2.0f / 320.0f ); ⤶ //⤶ // Work out our movement relative to our body rotation⤶ //⤶ var moveDir = WishVelocity.Normal; var forward = Rot.Forward.Dot( moveDir ); var sideward = Rot.Right.Dot( moveDir ); //⤶ // Set our speeds on the animgraph⤶ //⤶ SetParam( "forward", forward ); SetParam( "sideward", sideward );⤶ SetParam( "wishspeed", WishVelocity.Length );⤶ } } public class StandardPlayerAnimator : PawnAnimator⤶ { TimeSince TimeSinceFootShuffle = 60; ⤶ ⤶ float duck; ⤶ public override void Simulate() { var player = Pawn as Player;⤶ var idealRotation = Rotation.LookAt( Input.Rotation.Forward.WithZ( 0 ), Vector3.Up );⤶ ⤶ DoRotation( idealRotation ); DoWalk(); ⤶ //⤶ // Let the animation graph know some shit⤶ //⤶ bool sitting = HasTag( "sitting" ); bool noclip = HasTag( "noclip" ) && !sitting; ⤶ SetAnimParameter( "b_grounded", GroundEntity != null || noclip || sitting ); SetAnimParameter( "b_noclip", noclip );⤶ SetAnimParameter( "b_sit", sitting );⤶ SetAnimParameter( "b_swim", Pawn.WaterLevel > 0.5f && !sitting );⤶ ⤶ if ( Host.IsClient && Client.IsValid() ) { SetAnimParameter( "voice", Client.TimeSinceLastVoice < 0.5f ? Client.VoiceLevel : 0.0f );⤶ }⤶ ⤶ Vector3 aimPos = Pawn.EyePosition + Input.Rotation.Forward * 200; Vector3 lookPos = aimPos; ⤶ //⤶ // Look in the direction what the player's input is facing⤶ //⤶ SetLookAt( "aim_eyes", lookPos ); SetLookAt( "aim_head", lookPos ); SetLookAt( "aim_body", aimPos ); ⤶ if ( HasTag( "ducked" ) ) duck = duck.LerpTo( 1.0f, Time.Delta * 10.0f );⤶ else duck = duck.LerpTo( 0.0f, Time.Delta * 5.0f ); ⤶ SetAnimParameter( "duck", duck );⤶ ⤶ if ( player != null && player.ActiveChild is BaseCarriable carry )⤶ {⤶ carry.SimulateAnimator( this ); } else⤶ {⤶ SetAnimParameter( "holdtype", 0 );⤶ SetAnimParameter( "aim_body_weight", 0.5f ); } ⤶ } public virtual void DoRotation( Rotation idealRotation )⤶ {⤶ var player = Pawn as Player;⤶ //⤶ // Our ideal player model rotation is the way we're facing⤶ //⤶ var allowYawDiff = player?.ActiveChild == null ? 90 : 50; ⤶ float turnSpeed = 0.01f; if ( HasTag( "ducked" ) ) turnSpeed = 0.1f;⤶ ⤶ //⤶ // If we're moving, rotate to our ideal rotation⤶ //⤶ Rotation = Rotation.Slerp( Rotation, idealRotation, WishVelocity.Length * Time.Delta * turnSpeed );⤶ ⤶ //⤶ // Clamp the foot rotation to within 120 degrees of the ideal rotation⤶ //⤶ Rotation = Rotation.Clamp( idealRotation, allowYawDiff, out var change );⤶ ⤶ //⤶ // If we did restrict, and are standing still, add a foot shuffle⤶ //⤶ if ( change > 1 && WishVelocity.Length <= 1 ) TimeSinceFootShuffle = 0;⤶ ⤶ SetAnimParameter( "b_shuffle", TimeSinceFootShuffle < 0.1 );⤶ }⤶ ⤶ void DoWalk()⤶ {⤶ // Move Speed⤶ {⤶ var dir = Velocity;⤶ var forward = Rotation.Forward.Dot( dir );⤶ var sideward = Rotation.Right.Dot( dir );⤶ ⤶ var angle = MathF.Atan2( sideward, forward ).RadianToDegree().NormalizeDegrees();⤶ ⤶ SetAnimParameter( "move_direction", angle );⤶ SetAnimParameter( "move_speed", Velocity.Length );⤶ SetAnimParameter( "move_groundspeed", Velocity.WithZ( 0 ).Length );⤶ SetAnimParameter( "move_y", sideward );⤶ SetAnimParameter( "move_x", forward );⤶ SetAnimParameter( "move_z", Velocity.z );⤶ }⤶ ⤶ // Wish Speed⤶ {⤶ var dir = WishVelocity;⤶ var forward = Rotation.Forward.Dot( dir );⤶ var sideward = Rotation.Right.Dot( dir );⤶ ⤶ var angle = MathF.Atan2( sideward, forward ).RadianToDegree().NormalizeDegrees();⤶ ⤶ SetAnimParameter( "wish_direction", angle );⤶ SetAnimParameter( "wish_speed", WishVelocity.Length );⤶ SetAnimParameter( "wish_groundspeed", WishVelocity.WithZ( 0 ).Length );⤶ SetAnimParameter( "wish_y", sideward );⤶ SetAnimParameter( "wish_x", forward );⤶ SetAnimParameter( "wish_z", WishVelocity.z );⤶ }⤶ }⤶ ⤶ public override void OnEvent( string name )⤶ {⤶ // DebugOverlay.Text( Pos + Vector3.Up * 100, name, 5.0f );⤶ ⤶ if ( name == "jump" )⤶ {⤶ Trigger( "b_jump" );⤶ }⤶ ⤶ base.OnEvent( name );⤶ }⤶ }⤶ ``` # Setting Setting the Animator is the same as setting a <page>Player Controller</page>. ``` public override void Respawn() { base.Respawn(); Animator = new StandardPlayerAnimator(); } ``` Like the <page>Player Controller</page>, this property can be changed at any time and is replicated to the client. Setting to null will mean your player isn't animated.