251 lines
7.9 KiB
C#
251 lines
7.9 KiB
C#
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<Player>();
|
|
controller = GetComponent<CharacterController>();
|
|
}
|
|
|
|
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<bool>("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;
|
|
// }
|
|
|
|
|
|
}
|
|
|
|
}
|