using System;
using System.Collections;
using System.Collections.Generic;
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 Vector3 lastInteracDir;
private ClearCounter selectedCounter;
private bool isWalking; // camel case for fields
private void Awake()
{
if (Instance != null)
{
Debug.LogError("There has been more than one player instance !!!");
}
Instance = this;
}
private void Start()
{
gameInput.onInteractAction += GameInput_onInteractAction;
}
private void GameInput_onInteractAction(object sender, System.EventArgs e)
{
if (selectedCounter != null)
{
selectedCounter.Interact();
}
}
private void Update() // alwayys be explicit on showing accesor
{
HandleMovement();
HandleInteraction();
}
public bool IsWalking()
{
return isWalking;
}
private void HandleInteraction()
{
Vector2 inputVector = gameInput.GetMovementVectorNormalized();
Vector3 moveDir = new Vector3(inputVector.x, 0f, inputVector.y);
if (moveDir != Vector3.zero)
{
lastInteracDir = moveDir;
}
float interactionDistance = 2f;
if (Physics.Raycast(transform.position, lastInteracDir, out RaycastHit raycastHit, interactionDistance, countersLayerMask))
{
if (raycastHit.transform.TryGetComponent(out ClearCounter clearCounter))
{
// has clear counter !
// clearCounter.Interact();
if (clearCounter != selectedCounter)
{
SetSelectedCounter(selectedCounter);
}
}
else
{
SetSelectedCounter(null);
}
}
else
{
SetSelectedCounter(null);
}
}
private void HandleMovement()
{
Vector2 inputVector = gameInput.GetMovementVectorNormalized();
Vector3 moveDir = new Vector3(inputVector.x, 0f, inputVector.y); // to mvoe our player in 2d using 3d vectors
float moveDistance = moveSpeed * Time.deltaTime;
float playerRadius = 0.7f;
float playerHeight = 2f;
bool canMove = !Physics.CapsuleCast(transform.position, transform.position + Vector3.up * playerHeight, playerRadius, moveDir, moveDistance);
if (!canMove)
{
// can not move in the moveDir
// Attempt only X movement
Vector3 moveDirX = new Vector3(moveDir.x, 0, 0).normalized;
canMove = !Physics.CapsuleCast(transform.position, transform.position + Vector3.up * playerHeight, playerRadius, moveDirX, moveDistance);
if (canMove)
{
// can move only in the X axis
moveDir = moveDirX;
}
else
{
// can not move only in the X axis
// attempt only z movememt
Vector3 moveDirZ = new Vector3(0, 0, moveDir.z).normalized;
canMove = !Physics.CapsuleCast(transform.position, transform.position + Vector3.up * playerHeight, playerRadius, moveDirZ, moveDistance);
if (canMove)
{
// can move only in the Z axis
moveDir = moveDirZ;
}
else
{
// can not move in any direction
}
}
}
if (canMove)
{
transform.position += moveDir * moveDistance; // here we are adding to make our player move
}
isWalking = moveDir != Vector3.zero; // the field
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
});
}
}