KitchenChaos/Assets/Scripts/Player.cs

178 lines
5.2 KiB
C#

using System;
using UnityEngine;
public class Player : MonoBehaviour, IKitchenObjectParent
{
public static Player Instance { get; private set; }
public Transform KitchenObjectHoldPoint { get; set; }
private const float playerRadius = .7f;
private const float playerHeight = 2f;
public event EventHandler OnPickedSomething;
[SerializeField] private GameInput gameInput;
[SerializeField] private float moveSpeed = 7f;
[SerializeField] private float rotateSpeed = 10f;
[SerializeField] private float interactDistance = 2f;
[SerializeField] private LayerMask countersLayerMask;
private Vector2 inputVector;
private bool isWalking;
private KitchenObject kitchenObject;
public KitchenObject KitchenObject
{
get => kitchenObject;
set
{
kitchenObject = value;
if (value != null)
{
OnPickedSomething?.Invoke(this, EventArgs.Empty);
}
}
}
private Vector3 lastInteractDir;
private Vector3 moveDir;
private BaseCounter selectedCounter;
private void Awake()
{
if (Instance != null)
{
Debug.LogError("There is more than one Player instance!");
}
Instance = this;
KitchenObjectHoldPoint = transform.Find("KitchenObjectHoldPoint");
}
private void Start()
{
gameInput.OnInteractAction += GameInput_OnInteractAction;
gameInput.OnInteractAlternateAction += GameInput_OnInteractAlternateAction;
}
private void Update()
{
HandleMovement();
HandleInteractions();
}
public event EventHandler<SelectedCounterChangedEventArgs> OnSelectedCounterChanged;
private void GameInput_OnInteractAlternateAction(object sender, System.EventArgs e)
{
if (!KitchenGameManager.Instance.IsGamePlaying())
{
return;
}
selectedCounter?.InteractAlternate(this);
}
private void GameInput_OnInteractAction(object sender, System.EventArgs e)
{
if (!KitchenGameManager.Instance.IsGamePlaying())
{
return;
}
selectedCounter?.Interact(this);
}
private void HandleInteractions()
{
if (moveDir != Vector3.zero)
{
lastInteractDir = moveDir;
}
if (Physics.Raycast(transform.position, lastInteractDir, out RaycastHit raycastHit, interactDistance, countersLayerMask))
{
if (raycastHit.transform.TryGetComponent(out BaseCounter baseCounter))
{
// Debug.Log("Player stands in front of a BaseCounter");
if (baseCounter != selectedCounter)
{
SetSelectedCounter(baseCounter);
}
}
else
{
SetSelectedCounter(null);
}
}
else
{
SetSelectedCounter(null);
}
}
private void SetSelectedCounter(BaseCounter sC)
{
selectedCounter = sC;
// Debug.Log(selectedCounter != null ? "SelectedCounter changed to BaseCounter" : "SelectedCounter changed to null");
OnSelectedCounterChanged?.Invoke(this, new() { SelectedCounter = sC });
}
public bool IsWalking()
{
return isWalking;
}
private void HandleMovement()
{
inputVector = GameInput.GetMovementVectorNormalized();
moveDir = new(inputVector.x, 0, inputVector.y);
float moveDistance = moveSpeed * Time.deltaTime;
bool canMove = !Physics.CapsuleCast(transform.position, transform.position + (Vector3.up * playerHeight), playerRadius, moveDir, moveDistance);
if (!canMove)
{
// Cannot move towars moveDir
//Attempt only x movement
Vector3 moveDirX = new Vector3(moveDir.x, 0, 0).normalized;
canMove = (moveDir.x < -.5f || moveDir.x > +.5f) && !Physics.CapsuleCast(transform.position, transform.position + (Vector3.up * playerHeight), playerRadius, moveDir, moveDistance);
if (canMove)
{
//Can move only on the X
MovePlayer(moveDirX, moveDistance);
}
else
{
//Cannot move only on the X
//Attempt only Z movement
Vector3 moveDirZ = new Vector3(0, 0, moveDir.z).normalized;
canMove = (moveDir.z < -.5f || moveDir.z > +.5f) && !Physics.CapsuleCast(transform.position, transform.position + (Vector3.up * playerHeight), playerRadius, moveDir, moveDistance);
if (canMove)
{
//Can move only on the Z
MovePlayer(moveDirZ, moveDistance);
}
else
{
//Cannot move in any direction
}
}
}
else
{
MovePlayer(moveDir, moveDistance);
}
isWalking = moveDir != Vector3.zero;
transform.forward = Vector3.Slerp(transform.forward, moveDir, Time.deltaTime * rotateSpeed);
}
private void MovePlayer(Vector3 moveDirection, float moveDistance)
{
transform.position += moveDirection * moveDistance;
}
}