Files
Crash-Course/Assets/Scripts/Player/UseItem.cs

180 lines
6.6 KiB
C#
Raw Normal View History

2025-03-29 15:18:27 -04:00
using System.Collections;
2025-04-17 18:32:27 -04:00
using UnityEngine;
using Game;
using Music;
using Player;
2025-04-18 15:54:50 -04:00
2025-04-16 19:57:54 -04:00
namespace Player
{
2025-04-18 15:54:50 -04:00
/// <summary>
/// This class allows a player to pick up, hold, and drop items during the game.
/// It is primarily used for managing interactions with the "hat" in "keep-away" mode.
/// </summary>
2025-04-17 18:32:27 -04:00
public class UseItem : MonoBehaviour
{
2025-04-18 15:54:50 -04:00
/// <summary>
/// The tag used to identify items that can be picked up.
/// </summary>
2025-04-17 18:32:27 -04:00
[SerializeField] private string itemTag;
2025-04-18 15:54:50 -04:00
/// <summary>
/// The item currently being held by the player.
/// </summary>
2025-04-17 18:32:27 -04:00
private GameObject heldItem;
2025-04-18 15:54:50 -04:00
/// <summary>
/// Whether the player is currently holding an item.
/// </summary>
2025-04-17 18:32:27 -04:00
private bool isHoldingItem = false;
2025-04-18 15:54:50 -04:00
/// <summary>
/// The time when the player started holding the item.
/// </summary>
2025-04-17 18:32:27 -04:00
private float holdStartTime;
2025-04-18 15:54:50 -04:00
/// <summary>
/// The total time the player has held the item.
/// </summary>
2025-04-17 18:32:27 -04:00
public float holdTime;
2025-04-18 15:54:50 -04:00
/// <summary>
/// Reference to the player's <see cref="Damageable"/> component.
/// </summary>
2025-04-17 18:32:27 -04:00
private Damageable damageable;
2025-04-18 15:54:50 -04:00
/// <summary>
/// The position where the item will be held (e.g., above the player's head).
/// </summary>
2025-04-17 18:32:27 -04:00
[SerializeField] public Transform head;
2025-03-29 15:18:27 -04:00
2025-04-18 15:54:50 -04:00
/// <summary>
/// Initializes the player's <see cref="Damageable"/> component.
/// </summary>
2025-04-17 18:32:27 -04:00
private void Start()
{
damageable = GetComponent<Damageable>();
}
2025-04-18 15:54:50 -04:00
/// <summary>
/// Updates the player's state every frame.
/// If the player is holding an item, it keeps the item positioned on their head
/// and updates the hold time in "keep-away" mode.
/// </summary>
private void Update()
{
2025-04-17 18:32:27 -04:00
if (isHoldingItem)
2025-03-20 14:45:29 -04:00
{
2025-04-18 15:54:50 -04:00
// Keeps the item positioned on the player's head
2025-04-17 18:32:27 -04:00
heldItem.transform.localPosition = Vector3.zero;
2025-04-18 15:54:50 -04:00
2025-04-17 18:32:27 -04:00
if (GameManager.gameMode == GameManager.GameMode.keepAway)
{
// Adds time to the player's leaderboard standing
holdTime += Time.deltaTime;
GameManager.Instance.UpdatePlayerHoldTime(gameObject, holdTime);
}
2025-03-20 14:45:29 -04:00
}
}
2025-02-17 19:02:14 -05:00
2025-04-18 15:54:50 -04:00
/// <summary>
/// Automatically picks up an item when the player collides with it.
/// </summary>
/// <param name="collision">The collision data from the item.</param>
private void OnCollisionEnter2D(Collision2D collision)
{
2025-04-18 15:54:50 -04:00
// Check if the collided object is a "hat" and the player is not already holding an item
2025-04-17 18:32:27 -04:00
if (collision.gameObject.CompareTag("Hat") && !isHoldingItem && !damageable.dying)
{
PickUpItem(collision.gameObject);
}
}
2025-04-18 15:54:50 -04:00
/// <summary>
/// Allows the player to pick up an item and start the hold timer.
/// </summary>
/// <param name="item">The item to pick up.</param>
public void PickUpItem(GameObject item)
2025-03-20 14:45:29 -04:00
{
2025-04-18 15:54:50 -04:00
// Prevent picking up items if the player is dying or the item is not interactable
if (damageable.dying) return;
if (HatRespawn.canBePickedUp == false) return;
2025-04-18 15:54:50 -04:00
// Set the item as the held item and update its state
2025-04-17 18:32:27 -04:00
heldItem = item;
isHoldingItem = true;
holdStartTime = Time.time;
item.GetComponent<Collider2D>().enabled = false;
item.GetComponent<Rigidbody2D>().bodyType = RigidbodyType2D.Static;
item.GetComponent<HatRespawn>().Interact();
item.transform.parent = head;
item.transform.localRotation = Quaternion.identity;
item.transform.localPosition = Vector3.zero;
2025-04-18 15:54:50 -04:00
// Initialize the player's hold time in the GameManager if not already set
2025-04-17 18:32:27 -04:00
if (!GameManager.playerHoldTimes.ContainsKey(gameObject))
{
GameManager.playerHoldTimes[gameObject] = 0f;
}
2025-04-18 15:54:50 -04:00
// Play the pickup sound and stop any ongoing hat movement
2025-04-17 18:32:27 -04:00
AudioManager.Instance.PlaySound("Pickup Hat");
GameManager.Instance.StopCoroutine("MoveHatToWinner");
}
2025-04-04 12:09:40 -04:00
2025-04-18 15:54:50 -04:00
/// <summary>
/// Allows the player to drop the item they are holding.
/// </summary>
public void DropItem()
{
2025-04-18 15:54:50 -04:00
// Prevent dropping items if the game is over
if (GameManager.Instance.gameOver) return;
2025-04-17 18:32:27 -04:00
if (isHoldingItem)
2025-03-20 14:45:29 -04:00
{
2025-04-18 15:54:50 -04:00
// Enable the item's collider and make it interactable after a short delay
2025-04-17 18:32:27 -04:00
heldItem.GetComponent<Collider2D>().enabled = true;
HatRespawn.canBePickedUp = false;
StartCoroutine(WaitForInteractability());
2025-04-18 15:54:50 -04:00
// Make the item dynamic and apply random force and torque to it
2025-04-17 18:32:27 -04:00
heldItem.GetComponent<Rigidbody2D>().bodyType = RigidbodyType2D.Dynamic;
heldItem.GetComponent<Rigidbody2D>().AddForce(Vector2.up * Random.Range(10f, 30f) + Vector2.right * Random.Range(-10, 10), ForceMode2D.Impulse);
2025-04-17 21:39:27 -04:00
heldItem.GetComponent<Rigidbody2D>().AddTorque(Random.Range(-1, 1), ForceMode2D.Impulse);
2025-04-18 15:54:50 -04:00
// Notify the item that it has been dropped
2025-04-17 18:32:27 -04:00
heldItem.GetComponent<HatRespawn>().OnHatDropped();
2025-04-18 15:54:50 -04:00
// Detach the item from the player
2025-04-17 18:32:27 -04:00
heldItem.transform.parent = GameManager.Instance.transform;
heldItem = null;
isHoldingItem = false;
2025-04-18 15:54:50 -04:00
// Remove the player's hold time from the GameManager
2025-04-17 18:32:27 -04:00
if (GameManager.playerHoldTimes.ContainsKey(gameObject))
{
GameManager.playerHoldTimes.Remove(gameObject);
}
2025-03-20 14:45:29 -04:00
}
}
2025-03-28 23:07:33 -04:00
2025-04-18 15:54:50 -04:00
/// <summary>
/// Waits for a short delay before making the item interactable again.
/// </summary>
/// <returns>An IEnumerator for coroutine execution.</returns>
2025-04-17 18:32:27 -04:00
private IEnumerator WaitForInteractability()
{
yield return new WaitForSeconds(0.1f);
HatRespawn.canBePickedUp = true;
}
2025-04-04 12:09:40 -04:00
2025-04-18 15:54:50 -04:00
/// <summary>
/// Checks if the player is currently holding an item.
/// </summary>
/// <returns>True if the player is holding an item, false otherwise.</returns>
2025-04-17 18:32:27 -04:00
public bool IsHoldingItem()
{
return isHoldingItem;
}
2025-04-04 12:09:40 -04:00
}
2025-04-18 15:54:50 -04:00
}