0% found this document useful (0 votes)
13 views

Player Movement

Uploaded by

saeedmodiri69
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views

Player Movement

Uploaded by

saeedmodiri69
Copyright
© © All Rights Reserved
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