Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class PlayerMovement: MonoBehaviourPun
- {
- [Header("Movement Settings")]
- public float maxVelocityGround = 15f;
- public float maxVelocityAir = 10f;
- public float groundAccelerate = 90f;
- public float airAccelerate = 180f;
- public float fallMultiplier = 1.2f;
- public float lookSens = 8f;
- public float slowDrag = 0;
- public float thrusterForce = 7f;
- public float friction = 10f;
- private float _friction = 0f;
- [Header("Rotation")]
- float xRot = 0F;
- float yRot = 0F;
- float minY = -90f;
- float maxY = 90f;
- Quaternion originalRotation;
- //More Movement Variables
- private float distToGround;
- private Vector3 _velocity;
- private Vector2 xyVelocity;
- [Header("References")]
- //public Text grounded;
- //public Text velocity;
- public Camera cam;
- private Move motor;
- private Rigidbody rb;
- private CapsuleCollider collidr;
- private GameObject rayPoint;
- //private PlayerSetup playerSetup;
- //Booleans
- private bool jumpy = false;
- void Start()
- {
- _friction = friction;
- //Locks the cursor to the middle of the screen, and hides it from view
- Cursor.lockState = CursorLockMode.Locked;
- Cursor.visible = false;
- //These attatch the correct objectss to their references in the script, defined above
- motor = GetComponent<Move>();
- rb = GetComponent<Rigidbody>();
- collidr = GetComponent<CapsuleCollider>();
- rayPoint = GameObject.Find("point");
- //playerSetup = GetComponent<PlayerSetup>();
- //Sets the distance to the ground from the center of the collider, used in determining whe nthe player is on the ground
- distToGround = collidr.bounds.extents.y;
- if (GetComponent<Rigidbody>())
- GetComponent<Rigidbody>().freezeRotation = true;
- originalRotation = transform.localRotation;
- }
- void FixedUpdate()
- {
- //Debug function that shows a visual representation of when the player is on the ground
- //string a = isGrounded().ToString();
- //grounded.GetComponent<Text>().text = a;
- //Finds the Velocity in the x plane. Also used in debug, as it shows it on screen
- //xyVelocity = new Vector2(rb.velocity.x, rb.velocity.z);
- //velocity.GetComponent<Text>().text = xyVelocity.magnitude.ToString("0.000");
- //This statement checks if the player both is on the ground, and has requested to jump. If so it will jump
- //while also not allowing multiple jumps while in the air. If the player holds it down, he will jump as soon
- //as he touches the ground, avoiding friction and allowing the player to bunnyhop
- if (Input.GetKey("space") && isGrounded())
- {
- rb.AddForce(Vector3.up * thrusterForce, ForceMode.Impulse);
- jumpy = true;
- }
- //rb.AddForce(Jump(), ForceMode.Impulse);
- //This makes you fall faster than you rise, and make jumping feel nicer overall.
- if (rb.velocity.y < 0)
- {
- rb.velocity += Vector3.up * Physics.gravity.y * fallMultiplier * Time.deltaTime;
- }
- //Gets the input from the axis'
- float input_y = Input.GetAxis("Vertical");
- float input_x = Input.GetAxis("Horizontal");
- //Calculates the direction we want to move in, taking into account mouse movement to allow for strafing
- Vector3 accelDir = (transform.forward * input_y + transform.right * input_x).normalized;
- //Checks if we are not pressing any inputs, and makes us decelerate faster, to make moving feel more snappy
- decelerate(accelDir);
- //This code adjusts the vector to be projected onto the plane that we are currently moving on. Makes strafing better
- RaycastHit hit;
- Physics.Raycast(collidr.center, Vector3.down, out hit, 1000);
- accelDir = Vector3.ProjectOnPlane(accelDir, hit.normal).normalized;
- //Finds the current velocity of our RIgidBody
- Vector3 curVel = rb.velocity;
- //Determines whether or not we want to use the air movement(ignore friction) or not.
- //The boolean checks if we have just jumped, so while we are still on the ground, we don't want to calculate friciton
- if (isGrounded() && jumpy == false)
- {
- _velocity = MoveGround(accelDir, curVel);
- }
- else
- {
- _velocity = MoveAir(accelDir, curVel);
- }
- //Apply Movement
- rb.velocity = _velocity;
- //These call the rotation functions below, one rotates the camera in the y plane, the other the rigidbody in the x plane, which has the camera as a child
- cameraRotate();
- rbRotate();
- jumpy = false;
- }
- private Vector3 MoveGround(Vector3 accelDir, Vector3 prevVelocity)
- {
- // Apply Friction
- float speed = prevVelocity.magnitude;
- if (speed != 0) // To avoid divide by zero errors
- {
- float drop = speed * _friction * Time.fixedDeltaTime;
- prevVelocity *= Mathf.Max(speed - drop, 0) / speed; // Scale the velocity based on friction.
- }
- return Accelerate(accelDir, prevVelocity, groundAccelerate, maxVelocityGround);
- }
- private Vector3 MoveAir(Vector3 accelDir, Vector3 prevVelocity)
- {
- return Accelerate(accelDir, prevVelocity, airAccelerate, maxVelocityAir);
- }
- private Vector3 Accelerate(Vector3 accelDir, Vector3 prevVelocity, float accelerate, float max_velocity)
- {
- float projVel = Vector3.Dot(prevVelocity, accelDir); // Vector projection of Current velocity onto accelDir.
- float accelVel = accelerate * Time.fixedDeltaTime; // Accelerated velocity in direction of movment
- // If necessary, truncate the accelerated velocity so the vector projection does not exceed max_velocity
- if (projVel + accelVel > max_velocity)
- {
- accelVel = max_velocity - projVel;
- };
- return prevVelocity + accelDir * accelVel;
- }
- //Function to check if we are on the ground
- public bool isGrounded()
- {
- return Physics.Raycast(collidr.bounds.center, Vector3.down, distToGround);
- //Below is a capsule cast, it would be better to implement because it has a thickness
- //return Physics.CheckCapsule(collider.bounds.center, new Vector3(collider.bounds.center.x, collider.bounds.min.y, collider.bounds.center.z), collider.radius * 0.9f);
- }
- /// <summary>
- /// decelerates us faster when not moving
- /// </summary>
- /// <param name="input"></param>
- public void decelerate(Vector3 input)
- {
- if (input == Vector3.zero)
- {
- _friction = 10f * friction;
- }
- else
- {
- _friction = friction;
- }
- }
- /// <summary>
- /// This function is the camera rotation function
- /// </summary>
- public void cameraRotate()
- {
- //Get the input from the mouse and multiply it by sensitivity so it can be adjusted from ingame
- yRot += Input.GetAxis("Mouse Y") * lookSens;
- //Clamp it so that we cant just keep spinning in the Y direction
- yRot = clamp(yRot, minY, maxY);
- //Calculate the quaternion using the amount of rotation found before. We use the negative mouse input as the amount
- //of rotation, and then specify that we want this rotation to be around the x axis. It seems counter intuitive, but this is the way to do it
- Quaternion yRotAngle = Quaternion.AngleAxis(-yRot, Vector3.right);
- //Apply this rotation to the cameras transform
- cam.transform.localRotation = originalRotation * yRotAngle;
- }
- /// <summary>
- /// Basically the same as above, but we dont need to clamp it because we want to be able to forever spin to the left and right
- /// </summary>
- public void rbRotate()
- {
- xRot += Input.GetAxis("Mouse X") * lookSens;
- Quaternion xRotAngle = Quaternion.AngleAxis(xRot, Vector3.up);
- rb.transform.localRotation = originalRotation * xRotAngle;
- }
- /// <summary>
- /// just clamps the angle we input between the next 2 floats
- /// </summary>
- /// <param name="angle">the float representation of the angle</param>
- /// <param name="min">the min that the angle can be</param>
- /// <param name="max">you got it by now right?></param>
- /// <returns></returns>
- private float clamp(float angle, float min, float max)
- {
- return Mathf.Clamp(angle, min, max);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement