using Godot; using System.Collections; using System.Collections.Generic; using Godot.Collections; namespace Rokojori { [Tool] [GlobalClass] public partial class CharacterMovement:CharacterControllerAction { [Export] public float onFloorMultiply = 1f; [Export] public float inAirMultiply = 0.01f; [Export] public CameraTargetOffset cameraTargetOffset; [ExportGroup( "Direction Source" )] [Export] public Node3D directionSource; public enum DirectionProcessing { None, Zero_Y_And_Normalize, Project_On_TransformPlane } [ExportGroup("Movement")] [Export] public float moveSpeed; [Export] public CharacterMovementType controllerMovementType; [Export] public CharacterMovementType mouseKeyboardMovementType; [Export] public CharacterMovementType currentMovementType; [Export] public Smoothing onFloorMovementSmoothing = new FrameSmoothing(); [Export] public Smoothing inAirMovementSmoothing = new FrameSmoothing(); [ExportGroup( "Rotation" )] [Export] public bool adjustRotation = true; [Export] public Curve forwardToRotationSmoothingFrames = MathX.Curve( 0, 1 ); [Export(PropertyHint.Range, "0,600")] public int airRotationSmoothingFrames = 120; FrameSmoothing rotationSmoothing = new FrameSmoothing(); protected CharacterMovementData characterMovementData = new CharacterMovementData(); protected override void _OnTrigger() { var onFloor = body.IsOnFloor(); characterMovementData.Reset( this ); if ( currentMovementType == null ) { return; } currentMovementType.ProcessMovement( characterMovementData ); if ( cameraTargetOffset != null ) { cameraTargetOffset.SetMovingForward( characterMovementData.isMovingForward ? 1f : 0f ); } var movementMultiply = onFloor ? onFloorMultiply : inAirMultiply; characterMovementData.movement *= movementMultiply; if ( adjustRotation ) { var nextRotation = Math3D.LookRotation( characterMovementData.forwardDirection ); var speed = MathX.Clamp01( characterMovementData.movement.Length() / moveSpeed ); if ( speed > 0 ) { Quaternion rotation; if ( onFloor ) { rotationSmoothing.frames = Mathf.Round( forwardToRotationSmoothingFrames.Sample( speed ) ); } else { rotationSmoothing.frames = airRotationSmoothingFrames; } rotation = rotationSmoothing.Smooth( nextRotation, controller.delta ); body.SetGlobalQuaternion( rotation ); } } var smoothedMovement = Vector3.Zero; if ( onFloor ) { smoothedMovement = onFloorMovementSmoothing.Smooth( characterMovementData.movement, controller.delta ); } else { smoothedMovement = inAirMovementSmoothing.Smooth( characterMovementData.movement, controller.delta ); } Velocity( smoothedMovement, onFloor ); } } }