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 ); } } }