159 lines
5.0 KiB
C#
159 lines
5.0 KiB
C#
using UnityEngine;
|
|
using Mirror;
|
|
|
|
[RequireComponent(typeof(Rigidbody))]
|
|
public class Movement : NetworkBehaviour
|
|
{
|
|
[Header("Movement")] public float walkSpeed = 5f;
|
|
public float sprintSpeed = 8f;
|
|
public float crouchSpeed = 2.5f;
|
|
public float jumpForce = 7f;
|
|
public float airControl = 0.5f;
|
|
public float groundDrag = 5f;
|
|
public float airDrag = 1f;
|
|
|
|
[Header("Ground Check")] public Transform groundCheck;
|
|
public float groundDistance = 0.4f;
|
|
public LayerMask groundMask;
|
|
|
|
[Header("References")] public PlayerCameraController cameraController;
|
|
public Transform orientation;
|
|
|
|
private Rigidbody rb;
|
|
private Vector3 moveDirection;
|
|
private bool isGrounded;
|
|
private float originalHeight;
|
|
private Vector3 originalScale;
|
|
private bool isCursorLocked = true;
|
|
|
|
private void Start()
|
|
{
|
|
if (!isLocalPlayer) return;
|
|
|
|
rb = GetComponent<Rigidbody>();
|
|
rb.freezeRotation = true;
|
|
originalHeight = transform.localScale.y;
|
|
originalScale = transform.localScale;
|
|
|
|
if (cameraController == null) cameraController = GetComponentInChildren<PlayerCameraController>();
|
|
if (orientation == null) CreateOrientation();
|
|
|
|
UpdateCursorState();
|
|
}
|
|
|
|
private void CreateOrientation()
|
|
{
|
|
orientation = new GameObject("Orientation").transform;
|
|
orientation.parent = transform;
|
|
orientation.localPosition = Vector3.zero;
|
|
orientation.localRotation = Quaternion.identity;
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (!isLocalPlayer) return;
|
|
|
|
HandleCursorToggle();
|
|
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
|
|
|
|
if (cameraController != null)
|
|
orientation.rotation = Quaternion.Euler(0, cameraController.transform.eulerAngles.y, 0);
|
|
|
|
HandleJump();
|
|
HandleCrouch();
|
|
SpeedControl();
|
|
ApplyDrag();
|
|
}
|
|
|
|
private void FixedUpdate()
|
|
{
|
|
if (!isLocalPlayer) return;
|
|
MovePlayer();
|
|
}
|
|
|
|
private void HandleCursorToggle()
|
|
{
|
|
if (Input.GetKeyDown(KeyCode.LeftAlt) || Input.GetKeyDown(KeyCode.RightAlt))
|
|
{
|
|
ToggleCursor();
|
|
}
|
|
}
|
|
|
|
private void ToggleCursor()
|
|
{
|
|
isCursorLocked = !isCursorLocked;
|
|
UpdateCursorState();
|
|
}
|
|
|
|
private void UpdateCursorState()
|
|
{
|
|
Cursor.lockState = isCursorLocked ? CursorLockMode.Locked : CursorLockMode.None;
|
|
Cursor.visible = !isCursorLocked;
|
|
|
|
if (cameraController != null)
|
|
cameraController.enabled = isCursorLocked;
|
|
}
|
|
|
|
private void MovePlayer()
|
|
{
|
|
float horizontal = Input.GetAxisRaw("Horizontal");
|
|
float vertical = Input.GetAxisRaw("Vertical");
|
|
moveDirection = orientation.forward * vertical + orientation.right * horizontal;
|
|
moveDirection = Vector3.ProjectOnPlane(moveDirection, Vector3.up).normalized;
|
|
|
|
float currentSpeed = GetCurrentSpeed();
|
|
float speedMultiplier = isGrounded ? 1f : airControl;
|
|
rb.AddForce(moveDirection * currentSpeed * 10f * speedMultiplier, ForceMode.Force);
|
|
}
|
|
|
|
private float GetCurrentSpeed()
|
|
{
|
|
if (Input.GetKey(KeyCode.LeftControl)) return crouchSpeed;
|
|
if (Input.GetKey(KeyCode.LeftShift)) return sprintSpeed;
|
|
return walkSpeed;
|
|
}
|
|
|
|
private void HandleJump()
|
|
{
|
|
if (Input.GetKeyDown(KeyCode.Space) && isGrounded)
|
|
{
|
|
rb.linearVelocity = new Vector3(rb.linearVelocity.x, 0f, rb.linearVelocity.z);
|
|
rb.AddForce(transform.up * jumpForce, ForceMode.Impulse);
|
|
if (cameraController != null) cameraController.JumpEffect();
|
|
}
|
|
}
|
|
|
|
private void HandleCrouch()
|
|
{
|
|
bool shouldCrouch = Input.GetKey(KeyCode.LeftControl);
|
|
float targetHeight = shouldCrouch ? originalHeight * 0.5f : originalHeight;
|
|
Vector3 newScale = new Vector3(originalScale.x, targetHeight, originalScale.z);
|
|
transform.localScale = Vector3.Lerp(transform.localScale, newScale, 10f * Time.deltaTime);
|
|
if (cameraController != null) cameraController.SetCrouch(shouldCrouch);
|
|
}
|
|
|
|
private void SpeedControl()
|
|
{
|
|
Vector3 flatVel = new Vector3(rb.linearVelocity.x, 0f, rb.linearVelocity.z);
|
|
float currentMaxSpeed = GetCurrentSpeed();
|
|
|
|
if (flatVel.magnitude > currentMaxSpeed)
|
|
{
|
|
Vector3 limitedVel = flatVel.normalized * currentMaxSpeed;
|
|
rb.linearVelocity = new Vector3(limitedVel.x, rb.linearVelocity.y, limitedVel.z);
|
|
}
|
|
|
|
if (rb.linearVelocity.y > 10f) rb.linearVelocity = new Vector3(rb.linearVelocity.x, 10f, rb.linearVelocity.z);
|
|
}
|
|
|
|
private void ApplyDrag() => rb.linearDamping = isGrounded ? groundDrag : airDrag;
|
|
|
|
private void OnDrawGizmosSelected()
|
|
{
|
|
if (groundCheck != null)
|
|
{
|
|
Gizmos.color = Color.yellow;
|
|
Gizmos.DrawWireSphere(groundCheck.position, groundDistance);
|
|
}
|
|
}
|
|
} |