using System; using Sirenix.OdinInspector; using UnityEditor; using UnityEngine; using Unity.Mathematics; using NodeCanvas.Framework; using Drawing; public class PlayerMovement : MonoBehaviour { // Speed public float baseMoveSpeed = 5f; public bool sprinting; public float sprintAddtnlSpeed = 3f; public float sprintAcceleration = 5f; private float sprintPower; // Gravity private float gravityScale = 0f; public float gravityAcceleration = 1f; public float groundJumpGravity; // TODO: If I add more types of jumps, turn this into a class that contains the gravity, strenghth, and deaccel of each jump public float airJumpGravity; // Rotation public float rotationSpeed = 5f; public bool justATest; // Jumping public float jumpHeight; public float jumpDeacceleration; public int airJumpsCount; public float airJumpStrength; public float airJumpDeacceleration; public float groundJumpStrength; public float groundJumpDeacceleration; [SerializeField] private float jumpPower; public int airJumpsRemaining; public JumpProfile groundJumpParams; public JumpProfile initialAirJumpParams; public JumpProfile followupAirJumpParams; public JumpProfile currentJump; // Raycasts public RaycastHit forwardRay; public RaycastHit leftRay; public RaycastHit rightRay; [Serializable] public class JumpProfile{ public float jumpGravityMultiplier; public float jumpHeightMultiplier; public float jumpDeaccelMultiplier; public bool active; public void UpdateActive(JumpProfile _active){ // if (Mathf.Approximately(_active.jumpHeightMultiplier, jumpHeightMultiplier)) { // return; // } active = true; } } // References private Player thisPlayer; private CharacterController controller; void Awake(){ thisPlayer = GetComponent(); controller = GetComponent(); } void OnDrawGizmos(){ } void Update(){ //CheckContinuedSprinting(); //ProcessFlatSurfaceMovement(); //ProcessRotation(); // // Debug Visualization Tools // groundJumpParams.UpdateActive(currentJump); // initialAirJumpParams.UpdateActive(currentJump); // followupAirJumpParams.UpdateActive(currentJump); Color forwardRayStatus = Color.red; if (forwardRay.collider&& forwardRay.transform.gameObject.layer == LayerMask.NameToLayer("Environment")){ forwardRayStatus = Color.green;} using (Draw.WithColor(forwardRayStatus)) { Draw.Line(transform.position + transform.up, transform.position + transform.forward * 2.5f + transform.up); } } void FixedUpdate(){ LayerMask environmentLayer = LayerMask.NameToLayer("Environment"); if (Physics.Raycast(transform.position + Vector3.up, transform.forward, out forwardRay, 2.5f, ~environmentLayer)){ thisPlayer.controls.graph.SendEvent("ForwardRay", true, null); } if (Physics.Raycast(transform.position + Vector3.up, transform.position + Vector3.left, out leftRay, maxDistance: 2f, ~environmentLayer )) { thisPlayer.controls.graph.SendEvent("LeftRay", true, null); } if (Physics.Raycast(transform.position + Vector3.up, transform.position + Vector3.right, out rightRay, maxDistance: 2f, ~environmentLayer )) { thisPlayer.controls.graph.SendEvent("RightRay", true, null); } } public void ProcessFlatSurfaceMovement(){ // Get current input direction Vector3 flatSurfaceDirection = Vector3.zero; if (controller.isGrounded) { Vector2 rawInput = thisPlayer.controls.rawMoveInput; flatSurfaceDirection = new(rawInput.x, 0, rawInput.y); } // Rotate input to forward direction for flat surface flatSurfaceDirection = transform.rotation * flatSurfaceDirection; // Finalize flat surface direction by adding speed flatSurfaceDirection *= CalculateSpeed(); // Calculate gravity if (!controller.isGrounded) { gravityScale = Mathf.Lerp(gravityScale, Physics.gravity.y, gravityAcceleration * Time.deltaTime); } else { gravityScale = -.01f; } Vector3 gravityDirection = -Physics.gravity * gravityScale; // Add and deteriorate jump Vector3 jumpDirection = Vector3.zero; jumpPower = Mathf.Lerp(jumpPower, 0f, jumpDeacceleration * Time.deltaTime); jumpDirection = new Vector3(0, jumpPower, 0); // Move character // controller.Move((flatSurfaceDirection + gravityDirection) * Time.deltaTime); // Reset Air Jumps and Jump Power on Grounded if (controller.isGrounded) { airJumpsRemaining = airJumpsCount; jumpPower = 0f; currentJump = null; } // Reset Gravity Scale upon gaining air if (!controller.isGrounded) { //gravityScale = 0; } } public void AllocationTest(){ justATest = !justATest; } public void ProcessRotation(){ // Get current input direction Vector2 rawInput = thisPlayer.controls.rawLookInput; // Rotate character (times 360 to account for a full rotation taking 360 seconds otherwise) // transform.Rotate(new Vector3(0, rawInput.x * rotationSpeed * 360f * Time.deltaTime)); } public void StartSprint(){ sprinting = true; } public float CalculateSpeed(){ // Calculate sprinting speed float outputSpeed = 0f; // Add base speed outputSpeed += baseMoveSpeed; // Add sprinting speed if (sprinting) { sprintPower = Mathf.Lerp(sprintPower, 1, sprintAcceleration * Time.deltaTime); outputSpeed += (sprintAddtnlSpeed * sprintPower); } else { outputSpeed += (sprintAddtnlSpeed * sprintPower); sprintPower = Mathf.Lerp(sprintPower, 0, sprintAcceleration * Time.deltaTime); } return outputSpeed; } void CheckContinuedSprinting(){ if (sprinting) { // Disable sprinting if analog stick is released too far if (thisPlayer.controls.rawMoveInput.sqrMagnitude < .5f) { sprinting = false; return; } // Disable sprinting if analog stick direction is not forward Vector2 rawInput = thisPlayer.controls.rawMoveInput; Vector3 rawInputToVector3 = new(rawInput.x, 0, rawInput.y); float sprintVectorDot = Vector3.Dot(transform.InverseTransformVector(transform.forward), rawInputToVector3); if (sprintVectorDot < 0.3f) { sprinting = false; } } } void StartJump(){ // Replaced with Jump Type System // if (controller.isGrounded) { // jumpPower = jumpHeight * groundJumpStrength; // } else if (!controller.isGrounded && airJumpsRemaining > 0) { // Debug.Log(controller.isGrounded); // jumpPower = jumpHeight * airJumpStrength; // airJumpsRemaining--; // } // if (controller.isGrounded) { // currentJump = groundJumpParams; // } else if (airJumpsRemaining > 2){ // currentJump = initialAirJumpParams; // airJumpsRemaining--; // } else if (airJumpsRemaining > 0) { // currentJump = followupAirJumpParams; // } // // if (currentJump != null) { // jumpPower = currentJump.jumpHeightMultiplier; // } } }