KitchenChaos/Assets/Scripts/Player.cs

158 lines
5.4 KiB
C#

using System;
using Unity.Netcode;
using UnityEngine;
public class Player : NetworkBehaviour, IKitchenObjectParent {
private Transform KitchenObjectHoldPoint { get; set; }
public static Player LocalInstance { get; private set; }
public KitchenObject KitchenObject {
get => kitchenObject;
set {
kitchenObject = value;
if (value == null) return;
OnPickedSomething?.Invoke(this, EventArgs.Empty);
OnAnyPickedSomething?.Invoke(this, EventArgs.Empty);
}
}
[SerializeField] private float moveSpeed = 7f;
[SerializeField] private float rotateSpeed = 10f;
[SerializeField] private float interactDistance = 2f;
[SerializeField] private LayerMask countersLayerMask;
private const float playerRadius = .7f;
private const float playerHeight = 2f;
private Vector2 inputVector;
private bool isWalking;
private KitchenObject kitchenObject;
private Vector3 lastInteractDir;
private Vector3 moveDir;
private BaseCounter selectedCounter;
private void Start() {
GameInput.Instance.OnInteractAction += GameInput_OnInteractAction;
GameInput.Instance.OnInteractAlternateAction += GameInput_OnInteractAlternateAction;
}
private void Update() {
if (!IsOwner) return;
HandleMovement();
HandleInteractions();
}
public Transform GetKitchenObjectFollowTransform() => KitchenObjectHoldPoint;
public NetworkObject GetNetworkObject() => NetworkObject;
public static event EventHandler OnAnyPlayerSpawned;
public static event EventHandler OnAnyPickedSomething;
public static void ResetStaticData() {
OnAnyPlayerSpawned = null;
OnAnyPickedSomething = null;
}
public event EventHandler OnPickedSomething;
public override void OnNetworkSpawn() {
if (IsOwner) {
LocalInstance = this;
KitchenObjectHoldPoint = transform.Find("KitchenObjectHoldPoint");
}
OnAnyPlayerSpawned?.Invoke(this, EventArgs.Empty);
}
public event EventHandler<SelectedCounterChangedEventArgs> OnSelectedCounterChanged;
private void GameInput_OnInteractAlternateAction(object sender, EventArgs e) {
if (!KitchenGameManager.Instance.IsGamePlaying()) return;
selectedCounter?.InteractAlternate(this);
}
private void GameInput_OnInteractAction(object sender, EventArgs e) {
if (!KitchenGameManager.Instance.IsGamePlaying()) return;
selectedCounter?.Interact(this);
}
private void HandleInteractions() {
inputVector = GameInput.GetMovementVectorNormalized();
if (moveDir != Vector3.zero) lastInteractDir = moveDir;
if (Physics.Raycast(transform.position, lastInteractDir, out RaycastHit raycastHit, interactDistance,
countersLayerMask)) {
if (raycastHit.transform.TryGetComponent(out BaseCounter baseCounter)) {
if (baseCounter != selectedCounter) SetSelectedCounter(baseCounter);
}
else {
SetSelectedCounter(null);
}
}
else {
SetSelectedCounter(null);
}
}
private void SetSelectedCounter(BaseCounter _selectedCounter) {
selectedCounter = _selectedCounter;
OnSelectedCounterChanged?.Invoke(this,
new SelectedCounterChangedEventArgs{ SelectedCounter = _selectedCounter });
}
public bool IsWalking() => isWalking;
private void HandleMovement() {
inputVector = GameInput.GetMovementVectorNormalized();
moveDir = new Vector3(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);
}
//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;
}