0% found this document useful (0 votes)
17 views12 pages

Player Movement

Uploaded by

saeedmodiri69
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views12 pages

Player Movement

Uploaded by

saeedmodiri69
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 12

using System;

using UnityEngine;

public class PlayerMovement : MonoBehaviour


{
[Header("Assignables")]
public Transform playerCam;
public Transform orientation;
private Collider playerCollider;
public Rigidbody rb;

[Space(10)]
public LayerMask whatIsGround;
public LayerMask whatIsWallrunnable;

[Header("MovementSettings")]
public float sensitivity = 10000f;
public float moveSpeed = 4500f;

public float walkSpeed = 20f;


public float runSpeed = 10f;
public bool grounded;
public bool onWall;
public float baseSpeed = 10f; // Base speed of the player
public float rampSpeedMultiplier = 1.5f; // Multiplier for ramp speed

[Header("Wall Run Settings")]


public float wallRunSpeed = 20f; // Speed while wall running
public float wallRunDuration = 2f; // How long the player can wall run
public float wallRunGravityReduction = 0.5f; // Gravity reduction during wall run
public float wallRunJumpForce = 10f; // Jump force off the wall
public float wallRunCooldown = 0.5f; // Cooldown between wall runs

[Header("Audio Settings")]
public AudioClip runningSound;
public AudioClip slidingSound;
private AudioSource runningAudioSource;
private AudioSource slidingAudioSource;

private float wallRunGravity = 1f;


private float maxSlopeAngle = 35f;
private float wallRunRotation;
private float slideSlowdown = 0.2f;
private float actualWallRotation;
private float wallRotationVel;
private float desiredX;
private float xRotation;
private float sensMultiplier = 2.25f;
private float jumpCooldown = 0.25f;
private float jumpForce = 550f;
private float x;
private float y;
private float vel;

private bool readyToJump;


private bool jumping;
private bool sprinting;
private bool crouching;
private bool wallRunning;
private bool cancelling;
private bool readyToWallrun = true;
private bool airborne;
private bool onGround;
private bool surfing;
private bool cancellingGrounded;
private bool cancellingWall;
private bool cancellingSurf;

private Vector3 grapplePoint;


private Vector3 normalVector;
private Vector3 wallNormalVector;
private Vector3 wallRunPos;
private Vector3 previousLookdir;

private int nw;

[Header("Vault Settings")]
public float vaultDistance = 1f;
public float vaultHeight = 1.5f; // Height to which player will teleport
private bool isVaulting = false;

[Header("Sliding Boost Settings")]


public float slidingBoostForce = 500f; // Boost force applied during sliding
public float slidingBoostDuration = 0.5f; // Duration of the sliding boost

public static PlayerMovement Instance { get; private set; }

private void Awake()


{
Instance = this;
rb = GetComponent<Rigidbody>();

runningAudioSource = gameObject.AddComponent<AudioSource>();
runningAudioSource.loop = true; // Ensure the sound loops while running

slidingAudioSource = gameObject.AddComponent<AudioSource>();
slidingAudioSource.loop = true; // Ensure the sound loops while sliding
}

private void Start()


{
playerCollider = GetComponent<Collider>();
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
readyToJump = true;
wallNormalVector = Vector3.up;
}

private void LateUpdate()


{
WallRunning();
}

private void FixedUpdate()


{
Movement();
}

private void Update()


{
if (!isVaulting)
{
MyInput();
Look();
}
CheckForVault();
}

private void MyInput()


{
x = Input.GetAxisRaw("Horizontal");
y = Input.GetAxisRaw("Vertical");
jumping = Input.GetButton("Jump");
crouching = Input.GetKey(KeyCode.LeftControl);
if (Input.GetKeyDown(KeyCode.LeftControl))
{
StartCrouch();
}
if (Input.GetKeyUp(KeyCode.LeftControl))
{
StopCrouch();
}
}

private void StartCrouch()


{
float num = 400f;
transform.localScale = new Vector3(1f, 0.5f, 1f);
transform.position = new Vector3(transform.position.x, transform.position.y -
0.5f, transform.position.z);
if (rb.velocity.magnitude > 0.1f && grounded)
{
rb.AddForce(orientation.transform.forward * num);
}

// Apply sliding boost if already sliding


if (crouching && rb.velocity.magnitude > 0.1f)
{
ApplySlidingBoost();
PlaySlidingSound();
}
}

private void StopCrouch()


{
transform.localScale = new Vector3(1f, 1.5f, 1f);
transform.position = new Vector3(transform.position.x, transform.position.y +
0.5f, transform.position.z);
StopSlidingSound();
}

private void Movement()


{
if (isVaulting)
return;

// Apply a small downward force to keep the player grounded


rb.AddForce(Vector3.down * Time.deltaTime * 10f);

Vector2 mag = FindVelRelativeToLook();


float num = mag.x;
float num2 = mag.y;

// CounterMovement method
CounterMovement(x, y, mag);

if (readyToJump && jumping)


{
Jump();
}

float targetSpeed = walkSpeed;


if (sprinting)
{
targetSpeed = runSpeed;
PlayRunningSound();
}
else
{
StopRunningSound();
}

// Adjust speed multiplier if the player is on a ramp


if (IsOnRamp())
{
targetSpeed *= rampSpeedMultiplier;
}

// Handle crouching and apply additional downward force


if (crouching && grounded && readyToJump)
{
rb.AddForce(Vector3.down * Time.deltaTime * 3000f);
return;
}

if (x > 0f && num > targetSpeed) x = 0f;


if (x < 0f && num < -targetSpeed) x = 0f;
if (y > 0f && num2 > targetSpeed) y = 0f;
if (y < 0f && num2 < -targetSpeed) y = 0f;

float moveMultiplier = grounded ? 1f : 0.5f;


if (crouching && grounded) moveMultiplier = 0f;

rb.AddForce(orientation.transform.forward * y * moveSpeed * Time.deltaTime


* moveMultiplier);
rb.AddForce(orientation.transform.right * x * moveSpeed * Time.deltaTime *
moveMultiplier);
}

private bool IsOnRamp()


{
RaycastHit hit;
if (Physics.Raycast(transform.position, Vector3.down, out hit,
playerCollider.bounds.extents.y + 0.1f))
{
float slopeAngle = Vector3.Angle(hit.normal, Vector3.up);
return slopeAngle > 0 && slopeAngle <= maxSlopeAngle;
}
return false;
}
private void PlayRunningSound()
{
if (runningSound != null && runningAudioSource.clip != runningSound)
{
runningAudioSource.clip = runningSound;
runningAudioSource.Play();
}
}

private void StopRunningSound()


{
if (runningAudioSource.isPlaying && runningAudioSource.clip == runningSound)
{
runningAudioSource.Stop();
}
}

private void PlaySlidingSound()


{
if (slidingSound != null && slidingAudioSource.clip != slidingSound)
{
slidingAudioSource.clip = slidingSound;
slidingAudioSource.Play();
}
}

private void StopSlidingSound()


{
if (slidingAudioSource.isPlaying && slidingAudioSource.clip == slidingSound)
{
slidingAudioSource.Stop();
}
}

private void ResetJump()


{
readyToJump = true;
}

private void Jump()


{
if ((grounded || wallRunning || surfing) && readyToJump)
{
MonoBehaviour.print("jumping");
Vector3 velocity = rb.velocity;
readyToJump = false;
rb.AddForce(Vector2.up * jumpForce * 1.5f);
rb.AddForce(normalVector * jumpForce * 0.5f);
if (rb.velocity.y < 0.5f)
{
rb.velocity = new Vector3(velocity.x, 0f, velocity.z);
}
else if (rb.velocity.y > 0f)
{
rb.velocity = new Vector3(velocity.x, velocity.y / 2f, velocity.z);
}
if (wallRunning)
{
rb.AddForce(wallNormalVector * jumpForce * 3f);
}
Invoke("ResetJump", jumpCooldown);
if (wallRunning)
{
wallRunning = false;
}
}
}

private void Look()


{
float mouseX = Input.GetAxis("Mouse X") * sensitivity * Time.fixedDeltaTime *
sensMultiplier;
float mouseY = Input.GetAxis("Mouse Y") * sensitivity * Time.fixedDeltaTime *
sensMultiplier;

desiredX = playerCam.transform.localRotation.eulerAngles.y + mouseX;


xRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation, -90f, 90f);

FindWallRunRotation();
actualWallRotation = Mathf.SmoothDamp(actualWallRotation, wallRunRotation, ref
wallRotationVel, 0.2f);
playerCam.transform.localRotation = Quaternion.Euler(xRotation, desiredX,
actualWallRotation);
orientation.transform.localRotation = Quaternion.Euler(0f, desiredX, 0f);
}

private void CounterMovement(float x, float y, Vector2 mag)


{
if (!grounded || jumping)
{
return;
}
float num = 0.16f;
float num2 = 0.01f;
if (crouching)
{
rb.AddForce(moveSpeed * Time.deltaTime * -rb.velocity.normalized *
slideSlowdown);
return;
}
if ((Math.Abs(mag.x) > num2 && Math.Abs(x) < 0.05f) || (mag.x < 0f - num2
&& x > 0f) || (mag.x > num2 && x < 0f))
{
rb.AddForce(moveSpeed * orientation.transform.right * Time.deltaTime *
(0f - mag.x) * num);
}
if ((Math.Abs(mag.y) > num2 && Math.Abs(y) < 0.05f) || (mag.y < 0f - num2
&& y > 0f) || (mag.y > num2 && y < 0f))
{
rb.AddForce(moveSpeed * orientation.transform.forward * Time.deltaTime
* (0f - mag.y) * num);
}
if (Mathf.Sqrt(Mathf.Pow(rb.velocity.x, 2f) + Mathf.Pow(rb.velocity.z, 2f))
> walkSpeed)
{
float num3 = rb.velocity.y;
Vector3 vector = rb.velocity.normalized * walkSpeed;
rb.velocity = new Vector3(vector.x, num3, vector.z);
}
}

private void ApplySlidingBoost()


{
if (crouching && rb.velocity.magnitude > 0.1f)
{
rb.AddForce(orientation.transform.forward * slidingBoostForce,
ForceMode.Impulse);
Invoke("ResetSlidingBoost", slidingBoostDuration);
}
}

private void ResetSlidingBoost()


{
// Optionally reset any values related to sliding boost if needed
}

public Vector2 FindVelRelativeToLook()


{
float current = orientation.transform.eulerAngles.y;
float target = Mathf.Atan2(rb.velocity.x, rb.velocity.z) * 57.29578f;
float num = Mathf.DeltaAngle(current, target);
float num2 = 90f - num;
float magnitude = rb.velocity.magnitude;
return new Vector2(y:
magnitude * Mathf.Cos(num * ((float)Math.PI / 180f)),
x: magnitude * Mathf.Cos(num2 * ((float)Math.PI / 180f)));
}

private void FindWallRunRotation()


{
if (!wallRunning)
{
wallRunRotation = 0f;
return;
}
_ = new Vector3(0f, playerCam.transform.rotation.y, 0f).normalized;
new Vector3(0f, 0f, 1f);
float num = 0f;
float current = playerCam.transform.rotation.eulerAngles.y;
if (Math.Abs(wallNormalVector.x - 1f) < 0.1f)
{
num = 90f;
}
else if (Math.Abs(wallNormalVector.x - -1f) < 0.1f)
{
num = 270f;
}
else if (Math.Abs(wallNormalVector.z - 1f) < 0.1f)
{
num = 0f;
}
else if (Math.Abs(wallNormalVector.z - -1f) < 0.1f)
{
num = 180f;
}
num = Vector3.SignedAngle(new Vector3(0f, 0f, 1f), wallNormalVector,
Vector3.up);
float num2 = Mathf.DeltaAngle(current, num);
wallRunRotation = (0f - num2 / 90f) * 15f;
if (!readyToWallrun)
{
return;
}
if ((Mathf.Abs(wallRunRotation) < 4f && y > 0f && Math.Abs(x) < 0.1f) ||
(Mathf.Abs(wallRunRotation) > 22f && y < 0f && Math.Abs(x) < 0.1f))
{
if (!cancelling)
{
cancelling = true;
CancelInvoke("CancelWallrun");
Invoke("CancelWallrun", 0.2f);
}
}
else
{
cancelling = false;
CancelInvoke("CancelWallrun");
}
}

private void CancelWallrun()


{
MonoBehaviour.print("cancelled");
Invoke("GetReadyToWallrun", 0.1f);
rb.AddForce(wallNormalVector * 600f);
readyToWallrun = false;
}

private void GetReadyToWallrun()


{
readyToWallrun = true;
}

private void WallRunning()


{
if (wallRunning)
{
rb.AddForce(-wallNormalVector * Time.deltaTime * moveSpeed);
rb.AddForce(Vector3.up * Time.deltaTime * rb.mass * 100f *
wallRunGravity);
}
}

private bool IsFloor(Vector3 v)


{
return Vector3.Angle(Vector3.up, v) < maxSlopeAngle;
}

private bool IsSurf(Vector3 v)


{
float num = Vector3.Angle(Vector3.up, v);
if (num < 89f)
{
return num > maxSlopeAngle;
}
return false;
}

private bool IsWall(Vector3 v)


{
return Math.Abs(90f - Vector3.Angle(Vector3.up, v)) < 0.1f;
}

private bool IsRoof(Vector3 v)


{
return v.y == -1f;
}

private void StartWallRun(Vector3 normal)


{
if (!grounded && readyToWallrun)
{
wallNormalVector = normal;
float num = 20f;
if (!wallRunning)
{
rb.velocity = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
rb.AddForce(Vector3.up * num, ForceMode.Impulse);
}
wallRunning = true;
}
}

private void OnCollisionStay(Collision other)


{
int layer = other.gameObject.layer;
if ((int)whatIsGround != ((int)whatIsGround | (1 << layer)))
{
return;
}
for (int i = 0; i < other.contactCount; i++)
{
Vector3 normal = other.contacts[i].normal;
if (IsFloor(normal))
{
if (wallRunning)
{
wallRunning = false;
}
grounded = true;
normalVector = normal;
cancellingGrounded = false;
CancelInvoke("StopGrounded");
}
if (IsWall(normal) && layer == LayerMask.NameToLayer("Ground"))
{
StartWallRun(normal);
onWall = true;
cancellingWall = false;
CancelInvoke("StopWall");
}
if (IsSurf(normal))
{
surfing = true;
cancellingSurf = false;
CancelInvoke("StopSurf");
}
IsRoof(normal);
}
float num = 3f;
if (!cancellingGrounded)
{
cancellingGrounded = true;
Invoke("StopGrounded", Time.deltaTime * num);
}
if (!cancellingWall)
{
cancellingWall = true;
Invoke("StopWall", Time.deltaTime * num);
}
if (!cancellingSurf)
{
cancellingSurf = true;
Invoke("StopSurf", Time.deltaTime * num);
}
}

private void StopGrounded()


{
grounded = false;
}

private void StopWall()


{
onWall = false;
wallRunning = false;
}

private void StopSurf()


{
surfing = false;
}

private void CheckForVault()


{
if (!grounded && !isVaulting && Physics.Raycast(playerCam.position,
playerCam.forward, out RaycastHit hit, vaultDistance))
{
if (hit.collider.CompareTag("Vaultable"))
{
StartVault(hit.point);
}
}
}
private void StartVault(Vector3 hitPoint)
{
isVaulting = true;
Vector3 vaultTargetPosition = hitPoint + Vector3.up * vaultHeight; //
Adjust this to your desired vault height

// Store current velocity


Vector3 currentVelocity = rb.velocity;

// Disable rigidbody physics temporarily


rb.isKinematic = true;

// Teleport to vault position


TeleportToVaultPosition(vaultTargetPosition);

// Restore velocity after vaulting


rb.velocity = currentVelocity;

// Re-enable rigidbody physics


rb.isKinematic = false;

// End vaulting process


EndVault();
}

private void TeleportToVaultPosition(Vector3 targetPosition)


{
transform.position = targetPosition;
EndVault();
}

private void EndVault()


{
isVaulting = false;
rb.isKinematic = false;
}

public Vector3 GetVelocity()


{
return rb.velocity;
}

public float GetFallSpeed()


{
return rb.velocity.y;
}

public Collider GetPlayerCollider()


{
return playerCollider;
}

public Transform GetPlayerCamTransform()


{
return playerCam.transform;
}

public bool IsCrouching()


{
return crouching;
}

public Rigidbody GetRb()


{
return rb;
}
}

You might also like