godot-karrot-starter-theme/Common/StateMachines/Custom/PlayerStateMachines/RootMotionBasePlayerState.cs
2024-11-12 18:09:47 +01:00

85 lines
2.8 KiB
C#

using System;
using System.Threading.Tasks;
using Godot;
namespace KarrotStarterTemplate.Common.StateMachines.Custom.PlayerStateMachines;
public enum ERootMotionAnimationDirection
{
Character,
Camera,
Input,
}
public partial class RootMotionBasePlayerState : BasePlayerState
{
[Export] public ERootMotionAnimationDirection animationDirectionType { get; set; } =
ERootMotionAnimationDirection.Input;
[Export] public bool updateDirectionOnProcess { get; set; }
[Export] public ERootMotionAnimationDirection noInputDirectionTypeFallback { get; set; } =
ERootMotionAnimationDirection.Camera;
private Vector2 _blendPosition;
private Vector3 _velocity = Vector3.Zero;
private Vector3 _animationDirection = Vector3.Zero;
protected override Task OnEnter()
{
_animationDirection = GetRootMotionDirection();
return base.OnEnter();
}
protected override void OnStateProcess(double delta)
{
var (x, y, z) = animationTree.GetRootMotionPosition() / 2f;
_velocity += new Vector3(-x, y, -z);
base.OnStateProcess(delta);
}
protected override void OnStatePhysicsProcess(double delta)
{
if (updateDirectionOnProcess)
{
_animationDirection = GetRootMotionDirection();
}
if (_animationDirection != Vector3.Zero)
{
characterBody.GlobalRotation = new Vector3(0,
Mathf.LerpAngle(characterBody.GlobalRotation.Y,
-Mathf.Atan2(_animationDirection.X, -_animationDirection.Z), 10 * (float)delta), 0);
}
Quaternion rotationQuaternion = characterBody.Transform.Basis.GetRotationQuaternion();
characterBody.Velocity = rotationQuaternion.Normalized() * _velocity / (float)delta;
characterBody.MoveAndSlide();
_velocity = Vector3.Zero;
}
private Vector3 GetRootMotionDirection()
{
ERootMotionAnimationDirection temp = animationDirectionType;
if (temp == ERootMotionAnimationDirection.Input && package.GetVector3("move_direction").IsZeroApprox())
{
temp = noInputDirectionTypeFallback;
}
switch (temp)
{
case ERootMotionAnimationDirection.Character:
return Vector3.Zero;
case ERootMotionAnimationDirection.Camera:
return (-cameraController.camera.GlobalBasis.Z);
case ERootMotionAnimationDirection.Input:
return (cameraController.camera.GlobalBasis.Z * package.GetVector3("move_direction").Y) +
cameraController.camera.GlobalBasis.X * package.GetVector3("move_direction").X;
default:
throw new ArgumentOutOfRangeException();
}
}
}