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 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; } }