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(); cameraController = GetComponent(); } // Update is called once per frame void Update() { moveDir = Vector3.zero; if (hasControl) { if (!isDigging) { RotatePlayerTowardMouse(); TryInteract(); } DigDetector(); ApplyWalk(); // TODO: This is just for testing, remove or clean up if used if (Input.GetKeyDown(KeyCode.LeftShift)) { cameraController.RotateCam(); } // TODO: Add actual save feature later, this is just for test if (Input.GetKeyDown(KeyCode.I)) { SaveSystem.Save(); } } ApplyGravity(); DoMovement(); } /// /// Apply walking inputs to moveDir /// void ApplyWalk() { 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); } } /// /// Apply gravity to moveDir /// void ApplyGravity() { moveDir *= walkSpeed; if (!characterController.isGrounded) { moveDir.y = -gravity; } } /// /// Move character with moveDir /// void DoMovement() { characterController.Move(moveDir * Time.deltaTime); } /// /// Pass movement into character controller, lets us expose function without exposing /// whole char controller /// public void CharacterControllerMove(Vector3 movement) { characterController.Move(movement); } /// /// Auto-walk the character in the specified direction. Uses character's walk /// speed and camera rotation (per-frame) /// public void WalkInDirection(Vector3 direction) { Vector3 forwardDir = direction; forwardDir.y = 0; // don't move on the y axis forwardDir *= walkSpeed; characterController.Move(forwardDir * Time.deltaTime); } /// /// Detect input for digging (will eventually be tool agnostic) /// 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; } } } /// /// Face character graphic toward mouse /// 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; } } /// /// Try to interact by detecting nearest interactable /// void TryInteract() { if (Input.GetKeyDown(KeyCode.E) && nearestInteractable != null) { nearestInteractable.Interact(); } } private void OnTriggerEnter(Collider other) { Interactable interactable = other.GetComponent(); // 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(); // store nearest interactable if it exists if (interactable != null && nearestInteractable != null) { nearestInteractable.MoveOutsideRange(); nearestInteractable = null; } } /// /// Sets the character's "hasControl" bool. All input is ignored when false /// public void SetCharacterControl(bool hasControl) { this.hasControl = hasControl; } /// /// Gets the character's "hasControl" bool. All input is ignored when false /// public bool GetCharacterHasControl() { return hasControl; } }