Demo/DemoCharacterAnimator.cs
using Andicraft.SecondOrderDynamics;
using Sandbox;
[Title("[DEMO] Character Animator"), Category("Second Order Dynamics (Demo)")]
public class DemoCharacterAnimator : Component
{
private PlayerController _playerController;
#region Body
[Feature("Body"), Property] public GameObject BodyObject { get; set; }
[Feature("Body"), Property] public float BodyHeightOffset { get; set; }
[Feature("Body"), Property] public float BodyCrouchOffset { get; set; }
[Feature("Body"), Property] public DynamicsParameters BodyPosParameters { get; set; } = new();
[Feature("Body"), Property] public DynamicsParameters BodyRotParameters { get; set; } = new();
private Vector3Dynamics _bodyPosDynamics;
private RotationDynamics _bodyRotDynamics;
#endregion
#region Hands
[Feature( "Hands" ), Property] public GameObject HandsContainer;
[Feature("Hands"), Property] public DynamicsParameters HandsPosParameters { get; set; } = new();
[Feature("Hands"), Property] public DynamicsParameters HandsRotParameters { get; set; } = new();
private Vector3Dynamics _handsPosDynamics;
private RotationDynamics _handsRotDynamics;
#endregion
protected override void OnAwake()
{
_bodyPosDynamics = new Vector3Dynamics( BodyPosParameters, WorldPosition + Vector3.Up * BodyHeightOffset );
_bodyRotDynamics = new RotationDynamics( BodyRotParameters, WorldRotation );
_handsPosDynamics = new Vector3Dynamics( HandsPosParameters, WorldPosition + Vector3.Up * BodyHeightOffset );
_handsRotDynamics = new RotationDynamics( HandsRotParameters, WorldRotation );
_playerController = GetComponent<PlayerController>();
}
private Vector3 _forward = Vector3.Forward;
protected override void OnUpdate()
{
var vel = _playerController.Velocity;
var horizontalVel = new Vector3( vel.x, vel.y, 0 );
if (horizontalVel.Length > 3)
_forward = horizontalVel.Normal;
var targetLook = Rotation.LookAt( _forward );
var dirToFeet = Rotation.FromToRotation(Vector3.Up, (BodyObject.WorldPosition - WorldPosition).Normal);
var targetRot = Rotation.Identity * dirToFeet * targetLook;
var h = _playerController.IsDucking ? BodyCrouchOffset : BodyHeightOffset;
BodyObject.WorldRotation = _bodyRotDynamics.Update( Time.Delta, targetRot);
BodyObject.WorldPosition = _bodyPosDynamics.Update( Time.Delta, WorldPosition + Vector3.Up * h );
HandsContainer.WorldPosition = _handsPosDynamics.Update( Time.Delta, BodyObject.WorldPosition );
HandsContainer.WorldRotation = _handsRotDynamics.Update( Time.Delta, BodyObject.WorldRotation );
}
}