using UnityEngine;
public class Player : MonoBehaviour
{
[SerializeField] private float moveSpeed = 7f;
[SerializeField] private float rotationSpeed = 10f;
[SerializeField] private GameInput gameInput; //Reference to the GameInput script, which handles player input. This allows the Player script to read input from the GameInput script and respond accordingly.
private bool isWalking; //For Animator.
private Vector3 lastInteractDir; //For interactions.
private void Start()
{
gameInput.OnInteractAction += GameInput_OnInteractAction; //Subscribe to the OnInteractAction event from the GameInput script. This allows the Player script to respond when the player performs the interact action.
}
private void GameInput_OnInteractAction(object sender, System.EventArgs e)
{
Vector2 inputVector = gameInput.GetMovementVectorNormalized(); //Get the input vector from the GameInput script and normalize it.
Vector3 moveDir = new Vector3(inputVector.x, 0, inputVector.y); //Convert the 2D input vector to a 3D movement direction vector.
if (moveDir != Vector3.zero) //If the player is moving, set the last interact direction to the current movement direction. This allows the player to interact in the direction they are moving.
{
lastInteractDir = moveDir;
}
float interactDistance = 2f;
if(Physics.Raycast(transform.position, lastInteractDir, out RaycastHit raycastHit, interactDistance, LayerMask.GetMask("Counter"))) //Cast a ray in the direction of the last interact direction to check if there is a counter within interaction distance. If there is, check if it has a ClearCounter component and call the Interact method on it.
{
if (raycastHit.transform.TryGetComponent(out ClearCounter clearCounter)) //Check if the raycast hit a ClearCounter. If it did, call the Interact method on the ClearCounter.
{
clearCounter.Interact();
}
} else
{
Debug.Log("Raycast did not hit anything."); //Debug log to check if the raycast is not hitting anything.
}
Debug.DrawRay(transform.position, lastInteractDir * interactDistance, Color.red); //Debug ray to visualize the raycast in the Scene view.
}
private void Update()
{
HandleMovement();
HandleInteractions();
}
public bool IsWalking() //For Animator.
{
return isWalking;
}
private void HandleInteractions()
{
Vector2 inputVector = gameInput.GetMovementVectorNormalized(); //Get the input vector from the GameInput script and normalize it.
Vector3 moveDir = new Vector3(inputVector.x, 0, inputVector.y); //Convert the 2D input vector to a 3D movement direction vector.
if (moveDir != Vector3.zero) //If the player is moving, set the last interact direction to the current movement direction. This allows the player to interact in the direction they are moving.
{
lastInteractDir = moveDir;
}
float interactDistance = 2f;
if(Physics.Raycast(transform.position, lastInteractDir, out RaycastHit raycastHit, interactDistance, LayerMask.GetMask("Counter"))) //Cast a ray in the direction of the last interact direction to check if there is a counter within interaction distance. If there is, check if it has a ClearCounter component and call the Interact method on it.
{
if (raycastHit.transform.TryGetComponent(out ClearCounter clearCounter)) //Check if the raycast hit a ClearCounter. If it did, call the Interact method on the ClearCounter.
{
}
} else
{
}
Debug.DrawRay(transform.position, lastInteractDir * interactDistance, Color.red); //Debug ray to visualize the raycast in the Scene view.
}
private void HandleMovement()
{
Vector2 inputVector = gameInput.GetMovementVectorNormalized(); //Get the input vector from the GameInput script and normalize it.
Vector3 moveDir = new Vector3(inputVector.x, 0, inputVector.y); //Convert the 2D input vector to a 3D movement direction vector.
float moveDistance = moveSpeed * Time.deltaTime; //Calculate the distance the player will move this frame based on the move speed and delta time.
float playerRadius = .7f;
float playerHeight = 2f;
bool canMove = !Physics.CapsuleCast(transform.position, transform.position + Vector3.up * playerHeight, playerRadius, moveDir, moveDistance); //Check if there is an obstacle in the direction of movement using a raycast. If there is no obstacle, allow the player to move.
if (!canMove)
{
Vector3 moveDirX = new Vector3(moveDir.x, 0, 0).normalized;
canMove = !Physics.CapsuleCast(transform.position, transform.position + Vector3.up * playerHeight, playerRadius, moveDirX, moveDistance); //If there is an obstacle in the direction of movement, check if the player can move in the X direction.
if (canMove)
{
moveDir = moveDirX; //If the player can move in the X direction, set the movement direction to the X direction.
}
else
{
Vector3 moveDirZ = new Vector3(0, 0, moveDir.z).normalized;
canMove = !Physics.CapsuleCast(transform.position, transform.position + Vector3.up * playerHeight, playerRadius, moveDirZ, moveDistance); //If there is an obstacle in the X direction, check if the player can move in the Z direction.
if (canMove)
{
moveDir = moveDirZ; //If the player can move in the Z direction, set the movement direction to the Z direction.
}
}
}
if (canMove) //If there is no obstacle, move the player in the direction of movement.
{
transform.position += moveDir * moveDistance;
}
isWalking = moveDir != Vector3.zero; //Check if the player is moving, then set the isWalking variable for the Animator.
transform.forward = Vector3.Slerp(transform.forward, moveDir, Time.deltaTime * rotationSpeed); //Rotate the player in the direction of movement.
}
}