mirror of
https://github.com/Leahnaya/TheKingsRace.git
synced 2026-03-26 03:34:37 -05:00
Implemented Ragdoll kinda There are some issues with getting hit while ragdolling that need to be fixed Adjusted Dash Dash still needs some adjustments before being fully implemented
361 lines
10 KiB
C#
361 lines
10 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
public class PlayerMovement : MonoBehaviour
|
|
{
|
|
|
|
//Scripts
|
|
public PlayerStats pStats;
|
|
|
|
//Variable Section
|
|
/////
|
|
//Speed Variables
|
|
public Vector3 vel;
|
|
|
|
private Vector3 moveZ;
|
|
private Vector3 moveX;
|
|
private Vector3 driftVel;
|
|
|
|
//Character Moving
|
|
private CharacterController moveController;
|
|
|
|
//Jump value
|
|
private int curJumpNum;
|
|
private bool jumpPressed;
|
|
bool tempSet = false;
|
|
float tempTraction = 0.0f;
|
|
|
|
//Jump physics
|
|
private float mass = 5.0F; // defines the character mass
|
|
private Vector3 impact = Vector3.zero;
|
|
private float distToGround;
|
|
|
|
//Wallrunning
|
|
private WallRun wallRun;
|
|
|
|
//Ground Check
|
|
public bool isGrounded; //Better custom is grounded
|
|
public float groundCheckDistance = 0.05f; //how far away from the ground to not be considered grounded
|
|
private float lastTimeJumped = 0f; //Last time the player jumped
|
|
const float jumpGroundingPreventionTime = 0.2f; // delay in checking if we are grounded after a jump
|
|
const float groundCheckDistanceInAir = 0.07f; //How close we have to get to ground to start checking for grounded again
|
|
private Ray groundRay;
|
|
private RaycastHit groundHit;
|
|
|
|
//Camera Variables
|
|
private LayerMask ignoreP;
|
|
private Vector3 camRotation;
|
|
private Camera cam;
|
|
|
|
[Range(-45, -15)]
|
|
public int minAngle = -30;
|
|
[Range(30, 80)]
|
|
public int maxAngle = 45;
|
|
[Range(50, 500)]
|
|
public int sensitivity = 200;
|
|
|
|
//Ragdoll variables
|
|
private Vector3 hit;
|
|
private Rigidbody rB;
|
|
private bool firstHit = false;
|
|
private bool heldDown = false;
|
|
private Vector3 prevRot;
|
|
private Vector3 hitForce;
|
|
|
|
void Awake()
|
|
{
|
|
//Initialize Components
|
|
moveController = GetComponent<CharacterController>();
|
|
rB = GetComponent<Rigidbody>();
|
|
pStats = GetComponent<PlayerStats>();
|
|
|
|
//camera transform
|
|
cam = GetComponentInChildren<Camera>();
|
|
|
|
//Wallrun
|
|
//wallRun = gameObject.GetComponent<WallRun>();
|
|
}
|
|
|
|
void Start()
|
|
{
|
|
distToGround = GetComponent<Collider>().bounds.extents.y;
|
|
Cursor.lockState = CursorLockMode.Locked;
|
|
}
|
|
|
|
// Update is called once per frame
|
|
void FixedUpdate()
|
|
{
|
|
|
|
//Controls for camera
|
|
Rotation();
|
|
|
|
if(moveController.enabled == true){
|
|
|
|
//input controls for movement
|
|
InputController();
|
|
|
|
//if suffiecient impact magnitude is applied then move player
|
|
if (impact.magnitude > 0.2F) moveController.Move(impact * Time.deltaTime);
|
|
|
|
// consumes the impact energy each cycle:
|
|
impact = Vector3.Lerp(impact, Vector3.zero, 5*Time.deltaTime);
|
|
}
|
|
else{
|
|
|
|
//if suffiecient impact magnitude is applied then move player
|
|
if (rB.velocity.magnitude < 0.2f){
|
|
|
|
firstHit = false;
|
|
DisableRagdoll();
|
|
}
|
|
|
|
//Gravity without moveController
|
|
vel.y -= pStats.PlayerGrav * Time.deltaTime;
|
|
rB.AddForce(new Vector3(0,vel.y,0));
|
|
|
|
//Debug.LogWarning("MoveController is either Disabled or wasn't retrieved correctly");
|
|
}
|
|
|
|
//TESTING RAGDOLL STUFF NEEDS SOME WORk
|
|
/*
|
|
if (Input.GetMouseButton(1) && heldDown == false){
|
|
Debug.Log("yup");
|
|
getHit(new Vector3(1,1,1), 2000);
|
|
heldDown = true;
|
|
}
|
|
*/
|
|
|
|
if(!Input.GetMouseButton(1)){
|
|
heldDown = false;
|
|
}
|
|
|
|
//Checks if player should respawn
|
|
Respawn();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//Reads inputs and moves player
|
|
private void InputController()
|
|
{
|
|
//Check if player is grounded before each frame
|
|
GroundCheck();
|
|
//Keyboard inputs
|
|
|
|
//Checks if movement keys have been pressed and calculates correct vector
|
|
moveX = transform.right * Input.GetAxis("Horizontal") * Time.deltaTime * PlayerSpeed();
|
|
moveZ = transform.forward * Input.GetAxis("Vertical") * Time.deltaTime * PlayerSpeed();
|
|
|
|
//Adds vectors based on movement keys and other conditions to check what the
|
|
//player vector should be under the circumstances
|
|
vel = moveX + moveZ;
|
|
|
|
//Gravity
|
|
Gravity();
|
|
|
|
driftVel = Vector3.Lerp(driftVel, vel, pStats.Traction * Time.deltaTime);
|
|
//Jump Function
|
|
Jump();
|
|
|
|
moveController.Move(driftVel);
|
|
}
|
|
|
|
|
|
|
|
//Calculates speed current player needs to be going
|
|
public float PlayerSpeed()
|
|
{
|
|
//If nothing is pressed speed is 0
|
|
if (Input.GetAxis("Vertical") == 0.0f && Input.GetAxis("Horizontal") == 0.0f)
|
|
{
|
|
pStats.CurVel = 0.0f;
|
|
return pStats.CurVel;
|
|
}
|
|
//If current speed is below min when pressed set to minimum speed
|
|
else if (pStats.CurVel < pStats.MinVel)
|
|
{
|
|
pStats.CurVel = pStats.MinVel;
|
|
return pStats.MinVel;
|
|
}
|
|
// while the speed is below max speed slowly increase it
|
|
else if ((pStats.CurVel >= pStats.MinVel) && (pStats.CurVel < pStats.MaxVel))
|
|
{
|
|
pStats.CurVel += pStats.Acc;
|
|
return pStats.CurVel;
|
|
}
|
|
//If the players speed is above or equal to max speed set speed to max
|
|
else
|
|
{
|
|
pStats.CurVel = pStats.MaxVel;
|
|
return pStats.CurVel;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//Applies impact in a direction with the given force
|
|
public void AddImpact(Vector3 dir, float force)
|
|
{
|
|
dir.Normalize();
|
|
if (dir.y < 0) dir.y = -dir.y; // reflect down force on the ground
|
|
impact += dir.normalized * force / mass;
|
|
}
|
|
|
|
|
|
|
|
//Jump Function
|
|
private void Jump()
|
|
{
|
|
//If space is pressed apply an upwards force to the player
|
|
if (Input.GetAxis("Jump") != 0 && !jumpPressed && curJumpNum + 1 < pStats.JumpNum)
|
|
{
|
|
AddImpact(transform.up, pStats.JumpPow);
|
|
curJumpNum++;
|
|
jumpPressed = true;
|
|
}
|
|
|
|
lastTimeJumped = Time.time;
|
|
|
|
//If grounded no jumps have been used
|
|
if(isGrounded){
|
|
curJumpNum = 0;
|
|
}
|
|
|
|
//If space isn't being pressed then jump is false
|
|
if (Input.GetAxis("Jump") == 0) jumpPressed = false;
|
|
}
|
|
|
|
|
|
|
|
//PlayerScript
|
|
public bool GetJumpPressed(){
|
|
return jumpPressed;
|
|
}
|
|
|
|
public Camera GetPlayerCamera()
|
|
{
|
|
return cam;
|
|
}
|
|
|
|
public void AddPlayerVelocity(Vector3 additiveVelocity)
|
|
{
|
|
vel += additiveVelocity;
|
|
}
|
|
|
|
public void SetPlayerVelocity(Vector3 newVelocity)
|
|
{
|
|
vel = newVelocity;
|
|
}
|
|
|
|
|
|
|
|
//Camera and Player Rotation
|
|
private void Rotation()
|
|
{
|
|
transform.Rotate(Vector3.up * sensitivity * Time.deltaTime * Input.GetAxis("Mouse X"));
|
|
|
|
camRotation.x -= Input.GetAxis("Mouse Y") * sensitivity * Time.deltaTime;
|
|
camRotation.x = Mathf.Clamp(camRotation.x, minAngle, maxAngle);
|
|
|
|
cam.transform.localEulerAngles = camRotation;
|
|
}
|
|
|
|
|
|
|
|
//REMOVE WHEN UNNECCESARY
|
|
//Respawns player if they fall below a certain point
|
|
private void Respawn()
|
|
{
|
|
if (transform.position.y < -1)
|
|
{
|
|
transform.position = new Vector3(1f, 3f, 1f);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//Gravity Function for adjusting y-vel due to wallrun/glide/etc
|
|
private void Gravity(){
|
|
|
|
//Gliding
|
|
if(jumpPressed && pStats.HasGlider){
|
|
|
|
vel.y -= (pStats.PlayerGrav-18) * Time.deltaTime;
|
|
if(tempSet == false){
|
|
tempTraction = pStats.Traction;
|
|
pStats.Traction = 1.0f;
|
|
tempSet = true;
|
|
}
|
|
}
|
|
else{
|
|
|
|
if(tempSet == true){
|
|
pStats.Traction = tempTraction;
|
|
tempSet = false;
|
|
}
|
|
|
|
//Normal Gravity
|
|
vel.y -= pStats.PlayerGrav * Time.deltaTime;
|
|
}
|
|
|
|
//Wallrunning
|
|
if (pStats.HasWallrun) { wallRun.WallRunRoutine(); } //adjusted later if we are wallrunning
|
|
//If gliding
|
|
//Go down slowly
|
|
}
|
|
|
|
|
|
|
|
void GroundCheck()
|
|
{
|
|
// Make sure that the ground check distance while already in air is very small, to prevent suddenly snapping to ground
|
|
float chosenGroundCheckDistance = isGrounded ? (moveController.skinWidth + groundCheckDistance) : groundCheckDistanceInAir;
|
|
// reset values before the ground check
|
|
isGrounded = false;
|
|
groundRay = new Ray(moveController.transform.position, Vector3.down);
|
|
if (Physics.Raycast(groundRay, out groundHit, moveController.height + groundCheckDistance)) //&& Time.time >= lastTimeJumped + jumpGroundingPreventionTime) // only try to detect ground if it's been a short amount of time since last jump; otherwise we may snap to the ground instantly after we try jumping
|
|
{
|
|
// Only consider this a valid ground hit if the ground normal goes in the same direction as the character up
|
|
if (Vector3.Dot(groundHit.normal, transform.up) > 0f)
|
|
{
|
|
isGrounded = true;
|
|
// handle snapping to the ground
|
|
if (groundHit.distance > moveController.skinWidth)
|
|
{
|
|
moveController.Move(Vector3.down * groundHit.distance);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//Ragdoll Functions
|
|
private void getHit(Vector3 dir, float force){
|
|
if(firstHit == false){
|
|
EnableRagdoll();
|
|
dir.Normalize();
|
|
rB.AddForce(dir * force);
|
|
firstHit = true;
|
|
}
|
|
}
|
|
private void EnableRagdoll(){
|
|
prevRot = transform.localEulerAngles;
|
|
moveController.enabled = false;
|
|
rB.isKinematic = false;
|
|
rB.detectCollisions = true;
|
|
}
|
|
|
|
private void DisableRagdoll(){
|
|
moveController.enabled = true;
|
|
rB.isKinematic = true;
|
|
rB.detectCollisions = false;
|
|
transform.localEulerAngles = prevRot;
|
|
}
|
|
|
|
|
|
}
|