using System; using System.Linq; using NodeCanvas.Framework; using ParadoxNotion; using ParadoxNotion.Design; using UnityEngine; using UnityEngine.InputSystem; using Reset.Player.Movement; namespace NodeCanvas.Tasks.Actions { [Category("Reset/Movement")] public class AddJump : ActionTask { public BBParameter airMoveDirection; public BBParameter jumpPower; [Space(5)] public BBParameter jumpStrength; [SliderField(0, 1)] public BBParameter standStillJumpStrength; [Tooltip("Determines how much current movement vectors into jump direction")] [SliderField(0, 1)] public BBParameter currentVelocityInheritence; public BBParameter directionalForce; [SliderField(0, 1)] public BBParameter directionalForceStrength; protected override string info { get{ string dirStrength = ""; if (directionalForce.value != Vector3.zero && directionalForceStrength.value > 0f) { dirStrength = $", towards {directionalForce.value} * {directionalForceStrength.value}"; } return string.Format($"Start Jump, {jumpStrength.value} strength" + dirStrength); } } //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(){ 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(){ // Set jump power jumpPower.value = jumpStrength.value; // Save current velocity and get current input direction Vector3 currentVelocityVector3 = new Vector3(agent.velocity.x, 0f, agent.velocity.z); Vector2 currentInput = agent.GetComponent().rawMoveInput; Vector3 currentInputVector3 = new Vector3(currentInput.x, 0f, currentInput.y); // Ignore rotation for the current velocity Vector3 currentVelocityWorld = agent.transform.InverseTransformDirection(currentVelocityVector3.normalized); // Get the dot product between current velocity's direction and current input (UNUSED FOR NOW) float velocityInputDot = Vector3.Dot(currentVelocityWorld, currentInputVector3); // Set air move direction if (agent.isGrounded) { airMoveDirection.value = currentVelocityVector3; } else { // Hold new desired air direction and Dot against the existing air moving directioin Vector3 desiredAirMoveDirection = currentInputVector3; float airMoveDirectionDot = Vector3.Dot(desiredAirMoveDirection.normalized, airMoveDirection.value.normalized); // Check threshold of current XZ velocity- if it's too close to zero, use the jumpStrength for jumping velocity. If it's not, use the current velocity float velocityThreshold = 4f; float magnitudeZeroDifference = Mathf.Clamp(currentVelocityVector3.magnitude - velocityThreshold, 0f, Mathf.Infinity) / velocityThreshold; // Divided by maximum to return a 0-1 value. Clamping not required. float outputHoritontalVelocity = Mathf.Lerp(jumpStrength.value, currentVelocityVector3.magnitude, Math.Clamp(magnitudeZeroDifference, 0f, 1f)); outputHoritontalVelocity = Mathf.Min(outputHoritontalVelocity, Mathf.Lerp(standStillJumpStrength.value * jumpStrength.value, jumpStrength.value * .4f, magnitudeZeroDifference)); // Do the same for directional jump strength outputHoritontalVelocity = Mathf.Lerp(outputHoritontalVelocity, jumpStrength.value, directionalForceStrength.value); // Remap the dot to set -1 (opposing direction) to -.5f, and 1 (same direciton) to 1.2f // This is done to allow some sideways jumping direction change, but none backwards, and all forwards float remappedAirDirectionDot = Mathf.Lerp(.1f, 1.2f, airMoveDirectionDot); remappedAirDirectionDot = Mathf.Clamp(remappedAirDirectionDot, 0f, 1f); // Lerp between the current direction and the inputted direction based on the previous dot product Vector3 outputDirection = Vector3.Lerp(currentInputVector3.normalized, currentVelocityVector3.normalized, remappedAirDirectionDot); // If there is a directional force (such as the Wall Climb jump going straight upward) supplied in the task, lean into that based on it's strength outputDirection = Vector3.Lerp(outputDirection, directionalForce.value.normalized, directionalForceStrength.value).normalized; // Extra math to degrade current air move direction by velocity inheritence, before applying new air direction airMoveDirection.value *= currentVelocityInheritence.value; // Account for the camera's rotation before setting it as the air move direction outputDirection = Camera.main.transform.rotation.Flatten(0, null, 0) * outputDirection; // Set air move direction airMoveDirection.value += outputDirection * outputHoritontalVelocity; } EndAction(true); } //Called once per frame while the action is active. protected override void OnUpdate(){ } //Called when the task is disabled. protected override void OnStop() { } //Called when the task is paused. protected override void OnPause() { } } }