Final Player Controller
Davis Lang
using System;
using UnityEngine;
namespace UnityStandardAssets.Characters.FirstPerson
{
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(CapsuleCollider))]
public class RigidbodyFirstPersonController : MonoBehaviour
{
[Serializable]
public class MovementSettings
{
public float ForwardSpeed = 8.0f; // Speed when walking forward
public float BackwardSpeed = 4.0f; // Speed when walking backwards
public float StrafeSpeed = 4.0f; // Speed when walking sideways
public float SpeedInAir = 8.0f; // Speed when in air
public float RunMultiplier = 2.0f; // Speed multiplier when running
public float JumpForce = 30f;
[HideInInspector] public float CurrentTargetSpeed = 8f;
public void UpdateDesiredTargetSpeed(Vector2 input, bool isRunning)
{
if (input == Vector2.zero) return;
if (input.x > 0 || input.x < 0)
{
// Strafe
CurrentTargetSpeed = StrafeSpeed * (isRunning ? RunMultiplier : 1.0f);
}
if (input.y < 0)
{
// Backwards
CurrentTargetSpeed = BackwardSpeed * (isRunning ? RunMultiplier : 1.0f);
}
if (input.y > 0)
{
// Forwards
// Handled last as if strafing and moving forward at the same time, forwards speed should take precedence
CurrentTargetSpeed = ForwardSpeed * (isRunning ? RunMultiplier : 1.0f);
}
}
}
public bool canrotate;
public Camera cam;
public MovementSettings movementSettings = new MovementSettings();
public MouseLook mouseLook = new MouseLook();
public Vector3 relativevelocity;
public DetectObs detectGround;
public bool Wallrunning;
public float runningSwayAmount = 2.0f; // Adjust the amount of sway when running
public float bobbingSpeed = 1.0f; // Adjust the speed of bobbing
public float bobbingAmount = 0.5f; // Adjust the amount of bobbing
public float fovTransitionSpeed = 5.0f; // Adjust the speed of FOV transition
private Vector3 originalCameraPosition;
private Rigidbody m_RigidBody;
private CapsuleCollider m_Capsule;
private bool m_IsGrounded;
private bool m_IsRunning; // Flag to indicate whether the player is running
private bool isMoving; // Flag to indicate whether the player is moving
private float timer = 0.0f;
public float walkingFOV = 60f; // Default walking FOV
public float runningFOV = 70f; // FOV when running
public bool isPaused = false;
public Vector3 Velocity
{
get { return m_RigidBody.velocity; }
}
public bool Grounded
{
get { return m_IsGrounded; }
}
private void Awake()
{
canrotate = true;
m_RigidBody = GetComponent<Rigidbody>();
m_Capsule = GetComponent<CapsuleCollider>();
mouseLook.Init(transform, cam.transform);
originalCameraPosition = cam.transform.localPosition;
// Lock the cursor and hide it at the start of the game
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
private void Update()
{
if (!isPaused)
{
relativevelocity = transform.InverseTransformDirection(m_RigidBody.velocity);
if (m_IsGrounded)
{
if (Input.GetKeyDown(KeyCode.Space))
{
NormalJump();
AudioManager.Instance.PlaySFX("Jump");
}
}
// Check if left Shift key is pressed down to toggle running
if (Input.GetKeyDown(KeyCode.LeftShift))
{
m_IsRunning = true;
}
else if (Input.GetKeyUp(KeyCode.LeftShift))
{
m_IsRunning = false;
}
// Check if the player is moving
isMoving = Input.GetAxisRaw("Horizontal") != 0 || Input.GetAxisRaw("Vertical") != 0;
}
}
private void LateUpdate()
{
if (canrotate)
{
RotateView();
}
else
{
mouseLook.LookOveride(transform, cam.transform);
}
}
private void FixedUpdate()
{
if (!isPaused)
{
GroundCheck();
Vector2 input = GetInput();
float h = input.x;
float v = input.y;
Vector3 inputVector = new Vector3(h, 0, v);
inputVector = Vector3.ClampMagnitude(inputVector, 1);
// Grounded
if ((Mathf.Abs(input.x) > float.Epsilon || Mathf.Abs(input.y) > float.Epsilon) && m_IsGrounded && !Wallrunning)
{
movementSettings.UpdateDesiredTargetSpeed(input, m_IsRunning);
m_RigidBody.AddRelativeForce(inputVector * Time.deltaTime * 1000f * movementSettings.CurrentTargetSpeed);
}
// In air
else if ((Mathf.Abs(input.x) > float.Epsilon || Mathf.Abs(input.y) > float.Epsilon) && !m_IsGrounded && !Wallrunning)
{
movementSettings.UpdateDesiredTargetSpeed(input, m_IsRunning);
m_RigidBody.AddRelativeForce(inputVector * Time.deltaTime * 1000f * movementSettings.SpeedInAir * movementSettings.CurrentTargetSpeed);
}
}
}
public void NormalJump()
{
m_RigidBody.velocity = new Vector3(m_RigidBody.velocity.x, 0f, m_RigidBody.velocity.z);
m_RigidBody.AddForce(new Vector3(0f, movementSettings.JumpForce, 0f), ForceMode.Impulse);
}
private Vector2 GetInput()
{
Vector2 input = new Vector2
{
x = Input.GetAxisRaw("Horizontal"),
y = Input.GetAxisRaw("Vertical")
};
return input;
}
private void RotateView()
{
// Avoids the mouse looking if the game is effectively paused
if (Mathf.Abs(Time.timeScale) < float.Epsilon) return;
// Lock the cursor and hide it during gameplay
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
mouseLook.LookRotation(transform, cam.transform);
// Calculate sway based on movement speed
float swayAmount = isMoving && m_IsRunning ? runningSwayAmount : 0f;
float swayX = Input.GetAxis("Horizontal") * swayAmount * Time.deltaTime;
float swayY = Mathf.Sin(timer) * bobbingAmount;
// Increment timer based on bobbing speed
timer += bobbingSpeed * Time.deltaTime;
if (timer > Mathf.PI * 2)
{
timer = timer - (Mathf.PI * 2);
}
// Apply sway and bobbing
Vector3 sway = new Vector3(swayX, swayY, 0f);
cam.transform.localPosition = originalCameraPosition + sway;
// Smoothly transition FOV
float targetFOV = m_IsRunning && isMoving ? runningFOV : walkingFOV;
cam.fieldOfView = Mathf.Lerp(cam.fieldOfView, targetFOV, fovTransitionSpeed * Time.deltaTime);
}
// Add these fields to your class
private void GroundCheck()
{
if (detectGround.Obstruction)
{
m_IsGrounded = true;
}
else
{
m_IsGrounded = false;
}
}
}
}