85 lines
2.8 KiB
C#
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();
|
|
}
|
|
}
|
|
} |