161 lines
5.4 KiB
C#
161 lines
5.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Unity.Netcode;
|
|
using UnityEngine;
|
|
|
|
public class Player : NetworkBehaviour, IKitchenObjectParent {
|
|
private const float playerRadius = .7f;
|
|
// private const float playerHeight = 2f;
|
|
|
|
[SerializeField] private float MoveSpeed = 7f;
|
|
[SerializeField] private float RotateSpeed = 10f;
|
|
[SerializeField] private float InteractDistance = 2f;
|
|
[SerializeField] private LayerMask CountersLayerMask;
|
|
[SerializeField] private LayerMask CollisionsLayerMask;
|
|
[SerializeField] private List<Vector3> SpawnPositionList;
|
|
[SerializeField] private Transform KitchenObjectHoldPoint;
|
|
[SerializeField] private PlayerColor PlayerColor;
|
|
|
|
private Vector2 inputVector;
|
|
private bool isWalking;
|
|
private KitchenObject kitchenObject;
|
|
private Vector3 lastInteractDir;
|
|
private Vector3 moveDir;
|
|
private BaseCounter selectedCounter;
|
|
public static Player LocalInstance { get; private set; }
|
|
|
|
private void Start() {
|
|
GameInput.Instance.OnInteractAction += GameInput_OnInteractAction;
|
|
GameInput.Instance.OnInteractAlternateAction += GameInput_OnInteractAlternateAction;
|
|
PlayerData playerData = KitchenGameMultiplayer.Instance.GetPlayerDataFromClientId(OwnerClientId);
|
|
PlayerColor.SetPlayerColor(KitchenGameMultiplayer.Instance.GetPlayerColor(playerData.ColorId));
|
|
}
|
|
|
|
private void Update() {
|
|
if (!IsOwner) return;
|
|
|
|
HandleMovement();
|
|
HandleInteractions();
|
|
}
|
|
|
|
public KitchenObject KitchenObject {
|
|
get => kitchenObject;
|
|
set {
|
|
kitchenObject = value;
|
|
if (value is null) return;
|
|
|
|
OnPickedSomething?.Invoke(this, EventArgs.Empty);
|
|
OnAnyPickedSomething?.Invoke(this, EventArgs.Empty);
|
|
}
|
|
}
|
|
|
|
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");
|
|
}
|
|
|
|
transform.position = SpawnPositionList[KitchenGameMultiplayer.Instance.GetPlayerDataIndexFromClientId(OwnerClientId)];
|
|
OnAnyPlayerSpawned?.Invoke(this, EventArgs.Empty);
|
|
|
|
if (IsServer) NetworkManager.Singleton.OnClientDisconnectCallback += NetworkManager_OnClientDisconnectCallback;
|
|
}
|
|
|
|
private void NetworkManager_OnClientDisconnectCallback(ulong clientId) {
|
|
if (clientId == OwnerClientId && KitchenObject is not null) KitchenObject.DestroyKitchenObject(KitchenObject);
|
|
}
|
|
|
|
public event EventHandler<SelectedCounterChangedEventArgs> OnSelectedCounterChanged;
|
|
|
|
private void GameInput_OnInteractAlternateAction(object sender, EventArgs e) {
|
|
if (!KitchenGameManager.Instance.IsGamePlaying()) return;
|
|
if (selectedCounter != null) selectedCounter.InteractAlternate(this);
|
|
}
|
|
|
|
private void GameInput_OnInteractAction(object sender, EventArgs e) {
|
|
if (!KitchenGameManager.Instance.IsGamePlaying()) return;
|
|
if (selectedCounter != null) 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 value) {
|
|
selectedCounter = value;
|
|
OnSelectedCounterChanged?.Invoke(this, new() { SelectedCounter = value });
|
|
}
|
|
|
|
public bool IsWalking() => isWalking;
|
|
|
|
private void HandleMovement() {
|
|
inputVector = GameInput.GetMovementVectorNormalized();
|
|
|
|
moveDir = new(inputVector.x, 0, inputVector.y);
|
|
if (moveDir == Vector3.zero) return;
|
|
|
|
float moveDistance = MoveSpeed * Time.deltaTime;
|
|
Vector3 position = transform.position;
|
|
bool canMove = !Physics.BoxCast(position, Vector3.one * playerRadius, moveDir, Quaternion.identity, moveDistance, CollisionsLayerMask);
|
|
|
|
if (!canMove) {
|
|
// Cannot move towars moveDir
|
|
//Attempt only x movement
|
|
|
|
Vector3 moveDirX = new Vector3(moveDir.x, 0, 0).normalized;
|
|
canMove = moveDir.x is < -.5f or > +.5f && !Physics.BoxCast(position, Vector3.one * playerRadius, moveDirX, Quaternion.identity, moveDistance, CollisionsLayerMask);
|
|
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 is < -.5f or > +.5f && !Physics.BoxCast(position, Vector3.one * playerRadius, moveDirZ, Quaternion.identity, moveDistance, CollisionsLayerMask);
|
|
|
|
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;
|
|
} |