playtest-unity/playtest/Assets/Scripts/PlayerController.cs

103 lines
3.5 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(CharacterController))]
public class FPSController : MonoBehaviour
{
public Camera playerCamera;
public float walkSpeed = 9f;
public float runSpeed = 18f;
public float jumpPower = 7f;
public float gravity = 20f;
public float lookSpeed = 2f;
public float lookXLimit = 45f;
public float airAcceleration = 2f;
public float groundFriction = 6f;
Vector3 velocity = Vector3.zero;
float rotationX = 0;
public bool canMove = true;
CharacterController characterController;
void Start()
{
characterController = GetComponent<CharacterController>();
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
void Update()
{
Vector3 forward = playerCamera.transform.TransformDirection(Vector3.forward);
Vector3 right = playerCamera.transform.TransformDirection(Vector3.right);
forward.y = 0;
right.y = 0;
forward.Normalize();
right.Normalize();
bool isRunning = Input.GetKey(KeyCode.LeftShift);
float speed = isRunning ? runSpeed : walkSpeed;
Vector3 wishDir = forward * Input.GetAxis("Vertical") + right * Input.GetAxis("Horizontal");
if (characterController.isGrounded)
{
velocity.y = -0.5f; // Stick to the ground
if (canMove)
{
float drop = velocity.magnitude * groundFriction * Time.deltaTime;
velocity *= Mathf.Max(velocity.magnitude - drop, 0) / velocity.magnitude; // Apply friction
Accelerate(wishDir, speed, groundFriction); // Ground accelerate
if (Input.GetButton("Jump"))
{
velocity.y = jumpPower; // Jump
}
}
}
else
{
velocity.y -= gravity * Time.deltaTime; // Apply gravity
if (canMove)
{
// Air acceleration is now dependant on how aligned the move direction is with the current velocity direction
// The closer to straight ahead, the more acceleration, allowing for more maneuverability while keeping strafe speed under control
float currentSpeed = Vector3.Dot(velocity, wishDir);
float accel = airAcceleration * Mathf.Max(0, 1 - currentSpeed / speed);
Accelerate(wishDir, speed, accel);
}
}
// Apply movement
characterController.Move(velocity * Time.deltaTime);
// Looking
if (canMove)
{
rotationX += -Input.GetAxis("Mouse Y") * lookSpeed;
rotationX = Mathf.Clamp(rotationX, -lookXLimit, lookXLimit);
playerCamera.transform.localRotation = Quaternion.Euler(rotationX, 0, 0);
transform.rotation *= Quaternion.Euler(0, Input.GetAxis("Mouse X") * lookSpeed, 0);
}
}
// Acceleration function to add force to the velocity in the given direction
void Accelerate(Vector3 wishDir, float wishSpeed, float accel)
{
float currentSpeed = Vector3.Dot(velocity, wishDir);
float addSpeed = wishSpeed - currentSpeed;
if (addSpeed <= 0) return;
float accelerationSpeed = accel * Time.deltaTime * wishSpeed;
if (accelerationSpeed > addSpeed)
{
accelerationSpeed = addSpeed;
}
velocity += wishDir.normalized * accelerationSpeed;
}
}