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

158 lines
4.4 KiB
C#

using System;
using UnityEditorInternal;
using UnityEngine;
public class Player : MonoBehaviour
{
public static Player Instance { get; private set; }
public event EventHandler<OnSelectedCounterChangedEventArgs> OnSelectedcounterChanged;
public class OnSelectedCounterChangedEventArgs : EventArgs
{
public ClearCounter selectedCounter;
}
[SerializeField] private float moveSpeed = 7f;
[SerializeField] private GameInput gameInput;
[SerializeField] private LayerMask countersLayerMask;
private bool isWalking;
private Vector3 lastInteractDir;
private ClearCounter selectedCounter;
private void Start()
{
gameInput.OnInteractAction += GameInput_OnInteractAction;
}
private void GameInput_OnInteractAction(object sender, System.EventArgs e)
{
if (selectedCounter != null)
{
selectedCounter.Interact();
}
}
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 constantly 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;
if (Physics.Raycast(transform.position, lastInteractDir, out RaycastHit raycastHit, interactDistance, countersLayerMask))
{
if (raycastHit.transform.TryGetComponent(out ClearCounter clearCounter))
{
// Has Clear Counter
if (clearCounter != selectedCounter)
{
SetSelectedCounter(clearCounter);
}
}
else
{
SetSelectedCounter(null);
}
}
else
{
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;
bool canMove = !Physics.CapsuleCast(transform.position, transform.position + Vector3.up * playerHeight, playerRadius, moveDir, moveDistance);
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 (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 (canMove)
{
moveDir = moveDirZ;
}
else
{
// Cannot move at all
}
}
}
if (canMove)
{
transform.position += moveDir * moveDistance;
}
isWalking = moveDir != Vector3.zero;
float rotateSpeed = 10f;
transform.forward = Vector3.Slerp(transform.forward, moveDir, Time.deltaTime * rotateSpeed);
}
private void SetSelectedCounter(ClearCounter selectedCounter)
{
this.selectedCounter = selectedCounter;
OnSelectedcounterChanged?.Invoke(this, new OnSelectedCounterChangedEventArgs
{
selectedCounter = selectedCounter,
});
}
}