wirm/Game/Assets/Scripts/BedroomTask.cs

250 lines
8 KiB
C#
Raw Normal View History

/*
2025-02-14 21:56:25 +08:00
* Author: Reza
* Date: 3/2/25
* Description: To track if cleaning/exploring the bedroom task is done before allowing player to open the door
*/
using System.Collections;
using TMPro;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;
2025-02-14 21:56:25 +08:00
using UnityEngine.XR.Interaction.Toolkit.Interactables;
public class BedroomTask : MonoBehaviour
{
[Header("Task Requirement Values")]
// To track how much trash has been collected so far
2025-02-14 21:56:25 +08:00
public int trashCollected;
// Defines how much trash is needed to collect to unlock the door
public int trashRequired = 10;
2025-02-14 21:56:25 +08:00
// Defines the door
2025-02-14 21:56:25 +08:00
[Header("Door to Unlock")] public GameObject door;
// Defines UI references
2025-02-14 21:56:25 +08:00
[Header("UI References")] public GameObject lockedDoorUI;
public GameObject storyPanelUI;
public TMP_Text storyText;
2025-02-14 21:56:25 +08:00
2025-02-07 16:35:46 +08:00
// Defines Audio References
2025-02-14 21:56:25 +08:00
[Header("Audio References")] public AudioSource audioSource;
2025-02-07 16:35:46 +08:00
public AudioClip lockedSound;
public AudioClip unlockedSound;
public AudioClip footstepsSound;
public AudioClip doorSlamSound;
2025-02-11 15:01:17 +08:00
public AudioClip throwTrashSound;
2025-02-14 21:56:25 +08:00
// Defines the door handle
private Collider _doorCollider;
// Defines door's rigidbody to lock it
private Rigidbody _doorRigidbody;
private GameManager _gameManager;
// Defines the grab interactable to know when the door is grabbed
private XRGrabInteractable _grabInteractable;
private PostProcessingManager _postProcessingManager;
private void Start()
{
// Hide all UI prompts on start
lockedDoorUI.SetActive(false);
2025-02-11 15:01:17 +08:00
//unlockedDoorUI.SetActive(false);
2025-02-14 21:56:25 +08:00
// Ensure the door is not null
if (door != null)
{
// Get the components of the door
2025-02-14 21:56:25 +08:00
_grabInteractable = door.GetComponent<XRGrabInteractable>();
_doorCollider = door.GetComponent<Collider>();
_doorRigidbody = door.GetComponent<Rigidbody>();
// Ensure grab interactable is not null
2025-02-14 21:56:25 +08:00
if (_grabInteractable != null)
// Detect when the door is grabbed
2025-02-14 21:56:25 +08:00
_grabInteractable.selectEntered.AddListener(OnDoorGrabAttempt);
// Ensure rigidbody is not null
2025-02-14 21:56:25 +08:00
if (_doorRigidbody != null)
// Lock the door on start
2025-02-14 21:56:25 +08:00
LockDoor();
}
2025-02-14 21:56:25 +08:00
2025-02-13 15:11:41 +08:00
// Hide the story panel at the start
if (storyPanelUI != null)
storyPanelUI.SetActive(false);
// Subscribe to the event from DayPanelManager
CanvasFade.OnDayPanelHidden += ShowStoryText;
2025-02-14 21:56:25 +08:00
2025-02-13 15:11:41 +08:00
// if (storyPanelUI != null && storyText != null)
// {
// storyPanelUI.SetActive(true);
// storyText.text = "My parents are still home... I should clean up first.";
// StartCoroutine(ClearMessageAfterSeconds(7f));
// }
}
2025-02-14 21:56:25 +08:00
2025-02-13 15:11:41 +08:00
private void OnDestroy()
{
// Unsubscribe to prevent memory leaks
CanvasFade.OnDayPanelHidden -= ShowStoryText;
}
private void ShowStoryText()
{
// Activate story panel and show text after the Day Panel disappears
StartCoroutine(DelayedStoryText());
}
private IEnumerator DelayedStoryText()
{
2025-02-14 21:56:25 +08:00
yield return new WaitForSeconds(0.5f); // Small delay to ensure a smooth transition
2025-02-13 15:11:41 +08:00
2025-02-14 22:05:16 +08:00
if (!storyPanelUI || storyText == null) yield break;
storyPanelUI.SetActive(true);
storyText.text = "My parents are still home... I should clean up first.";
StartCoroutine(ClearMessageAfterSeconds(7f));
}
// Functions when trash is collected/thrown
public void CollectTrash()
{
// Add to trash count
trashCollected++;
2025-02-14 21:56:25 +08:00
2025-02-11 15:01:17 +08:00
// Play sound only if no other sound is currently playing
2025-02-14 21:56:25 +08:00
if (!audioSource.isPlaying) audioSource.PlayOneShot(throwTrashSound);
Debug.Log($"Trash collected: {trashCollected}/{trashRequired}");
2025-02-14 21:56:25 +08:00
// If the player has collected/ thrown the required amount of trash
2025-02-14 22:05:16 +08:00
if (trashCollected < trashRequired) return;
2025-02-14 22:19:28 +08:00
2025-02-14 22:05:16 +08:00
if (GameManager.Instance == null)
Debug.LogError("GameManager instance is null!");
else
GameManager.Instance.BedroomTaskComplete();
// Call unlocking door function/sequence
StartCoroutine(PlaySoundSequence());
}
2025-02-14 21:56:25 +08:00
// Functions when the door is locked
private void LockDoor()
{
// Ensure rigidbody is not null
2025-02-14 21:56:25 +08:00
if (_doorRigidbody != null)
{
// Stops door movement
2025-02-14 21:56:25 +08:00
_doorRigidbody.isKinematic = true;
// Freezes the door to ensure the door doesn't open
_doorRigidbody.constraints = RigidbodyConstraints.FreezeAll;
}
// Ensure collider is not null
2025-02-14 21:56:25 +08:00
if (_doorCollider != null)
// Prevents player from grabbing the door handle
_doorCollider.enabled = false;
}
// Functions when the door is unlocked
private void UnlockDoor()
{
// Ensure rigidbody is not null
if (_doorRigidbody)
{
// Allows door movement
2025-02-14 21:56:25 +08:00
_doorRigidbody.isKinematic = false;
// Unfreezes door to let it open
2025-02-14 21:56:25 +08:00
_doorRigidbody.constraints = RigidbodyConstraints.None;
}
// Ensure collider is not null
2025-02-14 21:56:25 +08:00
if (_doorCollider != null)
// Allows player to grab the door handle
2025-02-14 21:56:25 +08:00
_doorCollider.enabled = true;
// Play sound only if no other sound is currently playing
2025-02-14 21:56:25 +08:00
if (!audioSource.isPlaying) audioSource.PlayOneShot(unlockedSound);
// Show the unlocked door UI
2025-02-14 21:56:25 +08:00
// unlockedDoorUI.SetActive(true);
// Call the function to hide the UI after delay
2025-02-11 15:01:17 +08:00
//StartCoroutine(HideMessageAfterSeconds(unlockedDoorUI, 5f));
Debug.Log("Room is clean! The door is now unlocked.");
}
// Function when player tries to grab the door
private void OnDoorGrabAttempt(SelectEnterEventArgs args)
{
// If the amount of trash collected is lesser than the required amount
2025-02-14 22:05:16 +08:00
if (trashCollected >= trashRequired) return;
2025-02-14 21:56:25 +08:00
2025-02-14 22:05:16 +08:00
// Show the locked door UI
lockedDoorUI.SetActive(true);
2025-02-14 21:56:25 +08:00
2025-02-14 22:05:16 +08:00
// Play sound only if no other sound is currently playing
if (!audioSource.isPlaying) audioSource.PlayOneShot(lockedSound);
// Call the function to hide the UI after delay
StartCoroutine(HidePanelAfterSeconds(lockedDoorUI, 5f));
Debug.Log("The door is locked! Clean the room first.");
}
// Function when the task is completed
public bool IsTaskCompleted()
{
// Trash collected is more or equal to trash required to collect
return trashCollected >= trashRequired;
}
2025-02-14 21:56:25 +08:00
private IEnumerator PlaySoundSequence()
{
2025-02-11 15:01:17 +08:00
PostProcessingManager.Instance.TriggerEffect("Panic");
2025-02-14 21:56:25 +08:00
storyPanelUI.SetActive(true);
storyText.text = "!!!";
2025-02-14 21:56:25 +08:00
// Play footsteps of parents walking away
audioSource.PlayOneShot(footstepsSound);
yield return new WaitForSeconds(footstepsSound.length);
// Play a door slam after the footstep clip ends
audioSource.PlayOneShot(doorSlamSound);
yield return new WaitForSeconds(doorSlamSound.length);
2025-02-14 21:56:25 +08:00
2025-02-11 15:01:17 +08:00
// Stop the panic effect once the door slam sound ends
2025-02-13 19:49:34 +08:00
PostProcessingManager.Instance.StopEffect();
2025-02-14 21:56:25 +08:00
2025-02-10 12:54:56 +08:00
// Clear the "!!!"
storyText.text = "";
// Unlocks the door after the clips and update the story
UnlockDoor();
2025-02-14 21:56:25 +08:00
storyText.text = "They finally left... just as soon as I finished cleaning. I can leave the room now.";
StartCoroutine(ClearMessageAfterSeconds(7f));
}
2025-02-14 21:56:25 +08:00
// Function to hide the UI after a delay
2025-02-11 15:01:17 +08:00
private IEnumerator ClearMessageAfterSeconds(float delay)
{
// Waits for delay to end and hides the UI
yield return new WaitForSeconds(delay);
storyText.text = "";
}
2025-02-14 21:56:25 +08:00
2025-02-11 15:01:17 +08:00
private IEnumerator HidePanelAfterSeconds(GameObject uiElement, float delay)
{
2025-02-11 15:01:17 +08:00
// Waits for delay to end and hides the UI
yield return new WaitForSeconds(delay);
uiElement.SetActive(false);
2025-02-10 16:12:57 +08:00
}
2025-02-14 21:56:25 +08:00
}