rj-action-library/Runtime/Interactions/CharacterController/CharacterMovement.cs

149 lines
3.6 KiB
C#

using Godot;
using System.Collections;
using System.Collections.Generic;
using Godot.Collections;
namespace Rokojori
{
[GlobalClass]
public partial class CharacterMovement:CharacterControllerAction
{
[Export]
public float onFloorMultiply = 0f;
[Export]
public bool overwriteVelocity = true;
[ExportGroup( "Actions" )]
[Export]
public RJAction onMoving;
[Export]
public RJAction onIdle;
[Export]
public RJAction onForward;
[Export]
public RJAction onBackwards;
[Export]
public RJAction onStrafeLeft;
[Export]
public RJAction onStrafeRight;
[ExportGroup( "Direction Source" )]
[Export]
public Node3D directionSource;
public enum DirectionProcessing
{
None,
Zero_Y_And_Normalize,
Project_On_TransformPlane
}
[Export]
public DirectionProcessing directionProcessing;
[ExportGroup( "Moving" )]
[Export]
public float moveSpeed;
[Export]
public RJSensor forward;
[Export]
public RJSensor backwards;
[ExportGroup( "Strafing" )]
[Export]
public float strafeSpeed;
[Export]
public RJSensor strafeLeft;
[Export]
public RJSensor strafeRight;
[Export]
public bool useBodyDirection = true;
[ExportGroup( "Rotation" )]
[Export]
public bool adjustRotation = true;
[Export]
public Curve forwardToRotation = MathX.Curve( 0, 1 );
[Export( PropertyHint.Range, "0,1")]
public float rotationSmoothingCoefficient = 0.1f;
Smoother rotationSmoother = new Smoother();
public override void _OnTrigger()
{
if ( ! body.IsOnFloor() )
{
return;
}
var movement = Vector3.Zero;
var fw = Sensors.GetValue( forward );
var bw = Sensors.GetValue( backwards );
var fbAxis = Sensors.PolarAxis( backwards, forward );
var dir = directionSource != null ? directionSource : body;
var forwardDirection = dir.GlobalForward();
var rightDirection = useBodyDirection ? body.GlobalRight() : dir.GlobalRight();
if ( DirectionProcessing.Zero_Y_And_Normalize == directionProcessing )
{
forwardDirection.Y = 0;
rightDirection.Y = 0;
}
else if ( DirectionProcessing.Project_On_TransformPlane == directionProcessing )
{
var bodyPlane = Plane3.CreateFromNode3D( body );
forwardDirection = bodyPlane.ConstrainToPlane( forwardDirection + body.GlobalPosition ) - body.GlobalPosition;
rightDirection = bodyPlane.ConstrainToPlane( rightDirection + body.GlobalPosition ) - body.GlobalPosition;
}
forwardDirection = forwardDirection.Normalized();
rightDirection = rightDirection.Normalized();
movement += forwardDirection * Sensors.PolarAxis( backwards, forward ) * moveSpeed;
movement += rightDirection * Sensors.PolarAxis( strafeLeft, strafeRight ) * strafeSpeed ;
if ( body.IsOnFloor() )
{
movement *= onFloorMultiply;
}
if ( adjustRotation )
{
var currentRotation = body.GetGlobalQuaternion();
var nextRotation = Math3D.LookRotation( forwardDirection );
var sm = 1f - rotationSmoothingCoefficient;
sm = sm * sm;
var speed = MathX.Clamp01( movement.Length() / moveSpeed ) * Mathf.Max( fw, bw );
sm *= forwardToRotation.Sample( speed );
var rotation = rotationSmoother.SmoothWithCoefficient( currentRotation, nextRotation, sm, controller.delta );
body.SetGlobalQuaternion( rotation );
}
Velocity( movement, overwriteVelocity );
}
}
}