using System; using System.Collections; using NodeCanvas.Framework; using ParadoxNotion.Design; using ParadoxNotion.Services; using Unity.Cinemachine; using Unity.Mathematics; using UnityEngine; using Reset.Movement; namespace Reset.Movement{ public enum PlayerFacingDirection{ TowardsTarget = 0, MatchForward, MatchCamera, Static } } namespace NodeCanvas.Tasks.Actions { [Category("Reset/Movement")] [Description("Finalizes movement and sends the final move commands to the controller")] // TODO: Rename to UpdateMovementDirection public class UpdateMovementDirection : ActionTask{ [ParadoxNotion.Design.Header("References")] public BBParameter moveDirection; // TODO: Remove this reference and let each copy of this use their own settings. public BBParameter playerFacingDirection; [ParadoxNotion.Design.Header("Settings")] public BBParameter accelerationSmoothing = 5f; public BBParameter deaccelerationSmoothing = 5f; public BBParameter deaccelerationCurve; public BBParameter directionChangeMinimumMagnitude; // Unused. Use to only make input change if it's over a certain input threshold. Maybe smoothing can affect this? private float lastLookMagnitude; private Vector3 currentMoveDir; // References private PlayerControls controls; //Use for initialization. This is called only once in the lifetime of the task. //Return null if init was successfull. Return an error string otherwise protected override string OnInit() { // Reference to controls controls = agent.GetComponent(); return null; } //This is called once each time the task is enabled. //Call EndAction() to mark the action as finished, either in success or failure. //EndAction can be called from anywhere. protected override void OnExecute(){ // Initialize the smoothed direction with the value as is on input // currentMoveDir = new Vector3(moveDirection.value.x, moveDirection.value.y, moveDirection.value.z); } //Called once per frame while the action is active. protected override void OnUpdate(){ // Construct move direction Vector3 targetDirection = moveDirection.value; // Get input value Vector3 inputMovement = new Vector3(controls.rawMoveInput.x, 0f, controls.rawMoveInput.y); if (inputMovement.magnitude < .1f) { inputMovement = Vector3.zero; } // Change how movement is managed based on facing state switch (playerFacingDirection.value) { case PlayerFacingDirection.TowardsTarget: break; case PlayerFacingDirection.MatchForward: // TODO: Recomment // targetDirection = agent.transform.forward * inputMovement.magnitude; targetDirection = inputMovement; break; case PlayerFacingDirection.MatchCamera: targetDirection = Quaternion.Euler(Camera.main.transform.forward.DirectionTo(agent.transform.forward)) * inputMovement; // NOTE: This used to be t: currentRotSpeed * Time.deltaTime. // See how it feels with a hard set value and go fro there. break; case PlayerFacingDirection.Static: break; default: throw new ArgumentOutOfRangeException(); } // Remove Y from variables Vector3 targetNoY = new Vector3(targetDirection.x, 0f, targetDirection.z); Vector3 currentNoY = new Vector3(currentMoveDir.x, 0f, currentMoveDir.z); // Smooth movement if (targetNoY.magnitude > currentNoY.magnitude) { currentMoveDir = Vector3.Lerp(currentMoveDir, targetNoY,accelerationSmoothing.value * Time.deltaTime); } else { float deaccelValue = deaccelerationCurve.value.Evaluate(inputMovement.magnitude); currentMoveDir = Vector3.Lerp(currentMoveDir, targetNoY, deaccelerationSmoothing.value * Time.deltaTime); } currentMoveDir.y = moveDirection.value.y; // Commit move direction moveDirection.value = currentMoveDir; // Debug.Log(moveDirection.value); EndAction(true); } // Gravity is processed in LateUpdate (added to MonoManager's onLateUpdate in OnInit()) //Called when the task is disabled. protected override void OnStop() { EndAction(true); } //Called when the task is paused. protected override void OnPause() { } } }