This repository has been archived on 2025-03-20. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
mojo-kitchen-chaos/Assets/Scripts/Player.cs
BuyMyMojo 44837c6c13 Move container logic to use inheritence and move logic around.
Also fix the clear counter spawning items, next I'm going to implament the logic for placing food onto them instead.
2023-03-01 00:32:36 +11:00

200 lines
6.2 KiB
C#

using System.Collections;
using System.Collections.Generic;
using System;
using UnityEditorInternal;
using UnityEngine;
public class Player : MonoBehaviour, IKitchenObjectParent
{
public static Player Instance { get; private set; }
public event EventHandler<OnSelectedCounterChangedEventArgs> OnSelectedcounterChanged;
public class OnSelectedCounterChangedEventArgs : EventArgs
{
public BaseCounter selectedCounter;
}
[SerializeField] private float moveSpeed = 7f;
[SerializeField] private GameInput gameInput;
[SerializeField] private LayerMask countersLayerMask;
[SerializeField] private Transform kitchenObjectHoldPoint;
private bool isWalking;
private Vector3 lastInteractDir;
private BaseCounter selectedCounter;
private KitchenObject kitchenObject;
private void Start()
{
gameInput.OnInteractAction += GameInput_OnInteractAction;
}
private void GameInput_OnInteractAction(object sender, System.EventArgs e)
{
if (selectedCounter != null)
{
selectedCounter.Interact(this);
}
}
private void Awake()
{
if (Instance != null)
{
Debug.LogError("There is more than one player instance!");
}
Instance = this;
}
private void Update()
{
HandleMovement();
HandleInteractions();
}
public bool IsWalking()
{
return isWalking;
}
/// <summary>
/// Handle object interactions.
/// </summary>
private void HandleInteractions()
{
Vector2 inputVector = gameInput.GetMovementVectorNormalized();
Vector3 moveDir = new Vector3(inputVector.x, 0f, inputVector.y);
// Kepp a consistently updating record of the last move direction.
// This means you can interact without holding down a direction.
if (moveDir != Vector3.zero)
{
lastInteractDir = moveDir;
}
float interactDistance = 2f;
// fire a raycast forward to search for objects in the countersLayerMask and output result to raycastHit
if (Physics.Raycast(transform.position, lastInteractDir, out RaycastHit raycastHit, interactDistance, countersLayerMask))
{
// if the raycast hits an object of type BaseCounter
if (raycastHit.transform.TryGetComponent(out BaseCounter baseCounter))
{
// if selectedCounter is not equal to baseCounter update it
if (baseCounter != selectedCounter)
{
SetSelectedCounter(baseCounter);
}
}
// else if no BaseCounter was hit and selectedCounter isn't null then set it to null
else if (selectedCounter != null)
{
SetSelectedCounter(null);
}
}
// else if no BaseCounter was hit and selectedCounter isn't null then set it to null
else if (selectedCounter != null)
{
SetSelectedCounter(null);
}
}
/// <summary>
/// Handle the player movement and collision.
/// </summary>
private void HandleMovement()
{
Vector2 inputVector = gameInput.GetMovementVectorNormalized();
Vector3 moveDir = new Vector3(inputVector.x, 0f, inputVector.y);
float moveDistance = moveSpeed * Time.deltaTime;
float playerRadius = .7f;
float playerHeight = 2f;
// fire a CapsuleCast (A 3D raycast in the shape of a capsule) to see if there is an object in the way of the player movement.
bool canMove = !Physics.CapsuleCast(transform.position, transform.position + Vector3.up * playerHeight, playerRadius, moveDir, moveDistance);
// if the raycast hit something then this canMove is false and we attempt to move on eithery X or Z
if (!canMove)
{
// cannot move towards moveDir
// attempt only X move
Vector3 moveDirX = new Vector3(moveDir.x, 0, 0).normalized;
canMove = !Physics.CapsuleCast(transform.position, transform.position + Vector3.up * playerHeight, playerRadius, moveDirX, moveDistance);
// if able to move on X then change moveDir to X
if (canMove)
{
moveDir = moveDirX;
}
else
{
// cannot move on X so attempt to move on Z
Vector3 moveDirZ = new Vector3(0, 0, moveDir.z).normalized;
canMove = !Physics.CapsuleCast(transform.position, transform.position + Vector3.up * playerHeight, playerRadius, moveDirZ, moveDistance);
// if able to move on Z then change moveDir to Z
if (canMove)
{
moveDir = moveDirZ;
}
else
{
// cannot move at all so canMove is still false
}
}
}
if (canMove)
{
// add the time ajusted movement vector to current position which keep a consistent speed no matter the FPS
transform.position += moveDir * moveDistance;
}
// set isWalking to true if moveDir is not (0,0,0)
isWalking = moveDir != Vector3.zero;
float rotateSpeed = 10f;
// smothly rotate towards moveDir with a Slerp smoothed operation.
// Slerp is for like rotations while Lerp is for positions
transform.forward = Vector3.Slerp(transform.forward, moveDir, Time.deltaTime * rotateSpeed);
}
private void SetSelectedCounter(BaseCounter selectedCounter)
{
this.selectedCounter = selectedCounter;
OnSelectedcounterChanged?.Invoke(this, new OnSelectedCounterChangedEventArgs
{
selectedCounter = selectedCounter,
});
}
public Transform GetKitchenObjectFollowTransform()
{
return kitchenObjectHoldPoint;
}
public void SetKitchenObject(KitchenObject kitchenObject)
{
this.kitchenObject = kitchenObject;
}
public KitchenObject GetKitchenObject()
{
return kitchenObject;
}
public void ClearKitchenObject()
{
kitchenObject = null;
}
public bool HasKitchenObject()
{
return kitchenObject != null;
}
}