Files
DougDiggem/Assets/Scripts/PlayerController.cs
T
2026-02-27 23:55:04 -06:00

181 lines
4.9 KiB
C#

using System.Collections;
using UnityEngine;
using static UnityEngine.GraphicsBuffer;
public class PlayerController : MonoBehaviour
{
public GameObject DougBody;
public Shovel Shovel;
public float walkSpeed;
public float gravity = 10;
float digTime = 0.9f;
float digTimestamp = 0;
bool isDigging = false;
Interactable nearestInteractable;
private CharacterController characterController;
private CameraController cameraController;
private Vector3 moveDir;
private bool hasControl = true; // set this to false if we want to stop reading player inputs
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
characterController = GetComponent<CharacterController>();
cameraController = GetComponent<CameraController>();
}
// Update is called once per frame
void Update()
{
if (hasControl)
{
if (!isDigging)
{
RotatePlayerTowardMouse();
TryInteract();
}
Walk();
DigDetector();
// TODO: This is just for testing, remove or clean up if used
if (Input.GetKeyDown(KeyCode.LeftShift))
{
cameraController.RotateCam();
}
}
}
/// <summary>
/// Handle movement
/// </summary>
void Walk()
{
float verticalMovement = 0;
float horizontalMovement = 0;
if (!isDigging)
{
verticalMovement = Input.GetAxisRaw("Vertical");
horizontalMovement = Input.GetAxisRaw("Horizontal");
}
moveDir = new Vector3(horizontalMovement, 0, verticalMovement).normalized;
if (cameraController != null)
{
// re-matrix the rotation direction so movement is consistent no matter what
// the camera rotation is
Matrix4x4 matrix = Matrix4x4.Rotate(Quaternion.Euler(0, cameraController.playerCamHome.rotation.eulerAngles.y, 0));
moveDir = matrix.MultiplyPoint3x4(moveDir);
}
moveDir *= walkSpeed;
if (!characterController.isGrounded)
{
moveDir.y = -gravity;
}
characterController.Move(moveDir * Time.deltaTime);
}
/// <summary>
/// Detect input for digging (will eventually be tool agnostic)
/// </summary>
void DigDetector()
{
if (!isDigging)
{
if (Input.GetMouseButtonDown(0))
{
Shovel.Dig();
isDigging = true;
digTimestamp = Time.time + digTime; // fuck coroutines fr fr
}
}
else
{
if (Time.time > digTimestamp)
{
isDigging = false;
}
}
}
/// <summary>
/// Face character graphic toward mouse
/// </summary>
void RotatePlayerTowardMouse()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, Mathf.Infinity))
{
Vector3 targetPosition = hit.point;
targetPosition.y = transform.position.y;
Vector3 direction = targetPosition - transform.position;
Quaternion targetRotation = Quaternion.LookRotation(direction, Vector3.up);
DougBody.transform.rotation = targetRotation;
}
}
/// <summary>
/// Try to interact by detecting nearest interactable
/// </summary>
void TryInteract()
{
if (Input.GetKeyDown(KeyCode.E) && nearestInteractable != null)
{
nearestInteractable.Interact();
}
}
private void OnTriggerEnter(Collider other)
{
Interactable interactable = other.GetComponent<Interactable>();
// store nearest interactable if it exists
if (interactable != null)
{
nearestInteractable = interactable;
interactable.MoveInsideRange();
}
}
private void OnTriggerExit(Collider other)
{
// just null out interactables when we leave an interactable trigger (we cant and shouldn't overlap interactables)
Interactable interactable = other.GetComponent<Interactable>();
// store nearest interactable if it exists
if (interactable != null && nearestInteractable != null)
{
nearestInteractable.MoveOutsideRange();
nearestInteractable = null;
}
}
/// <summary>
/// Sets the character's "hasControl" bool. All input is ignored when false
/// </summary>
public void SetCharacterControl(bool hasControl)
{
this.hasControl = hasControl;
}
/// <summary>
/// Gets the character's "hasControl" bool. All input is ignored when false
/// </summary>
public bool GetCharacterHasControl()
{
return hasControl;
}
}