2025-12-03 17:23:18 +00:00
|
|
|
using UnityEngine;
|
2025-12-04 10:53:21 +00:00
|
|
|
using UnityEngine.SceneManagement;
|
2025-12-03 17:23:18 +00:00
|
|
|
|
|
|
|
|
public class StaircaseCurse : MonoBehaviour
|
|
|
|
|
{
|
|
|
|
|
[Header("Don't Look Back Settings")]
|
2025-12-04 10:53:21 +00:00
|
|
|
[Range(-1f, 1f)] public float killThreshold = -0.2f;
|
|
|
|
|
public GameObject blackScreenPanel;
|
2025-12-03 17:23:18 +00:00
|
|
|
|
|
|
|
|
[Header("Spooky Audio System")]
|
|
|
|
|
[Tooltip("Drag empty GameObjects with AudioSources from around the map here")]
|
2025-12-04 10:53:21 +00:00
|
|
|
public AudioSource[] environmentalSources;
|
2025-12-03 17:23:18 +00:00
|
|
|
public AudioClip[] scaryClips; // Whispers, footsteps, wood creaks
|
|
|
|
|
[Tooltip("Minimum seconds between random noises")]
|
|
|
|
|
public float minSoundDelay = 2f;
|
|
|
|
|
[Tooltip("Maximum seconds between random noises")]
|
|
|
|
|
public float maxSoundDelay = 5f;
|
|
|
|
|
|
|
|
|
|
// Internal State
|
|
|
|
|
private bool playerOnStairs = false;
|
|
|
|
|
private Transform playerTransform;
|
|
|
|
|
private bool isDead = false;
|
|
|
|
|
private float soundTimer;
|
|
|
|
|
|
|
|
|
|
void Start()
|
|
|
|
|
{
|
|
|
|
|
// Initialize timer
|
|
|
|
|
soundTimer = Random.Range(minSoundDelay, maxSoundDelay);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Update()
|
|
|
|
|
{
|
|
|
|
|
if (isDead || !playerOnStairs) return;
|
|
|
|
|
|
|
|
|
|
// 1. CHECK LIGHTS & FACING DIRECTION
|
|
|
|
|
// If lights are OFF, the curse is active
|
|
|
|
|
if (GameManager.Instance != null && !GameManager.Instance.AreAnyLightsOn())
|
|
|
|
|
{
|
|
|
|
|
CheckPlayerFacing();
|
2025-12-04 10:53:21 +00:00
|
|
|
|
2025-12-03 17:23:18 +00:00
|
|
|
// 2. HANDLE RANDOM AUDIO
|
|
|
|
|
HandleAudio();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HandleAudio()
|
|
|
|
|
{
|
|
|
|
|
soundTimer -= Time.deltaTime;
|
2025-12-04 10:53:21 +00:00
|
|
|
|
2025-12-03 17:23:18 +00:00
|
|
|
if (soundTimer <= 0)
|
|
|
|
|
{
|
|
|
|
|
PlayRandomSound();
|
|
|
|
|
// Reset timer
|
|
|
|
|
soundTimer = Random.Range(minSoundDelay, maxSoundDelay);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PlayRandomSound()
|
|
|
|
|
{
|
|
|
|
|
if (environmentalSources.Length == 0 || scaryClips.Length == 0) return;
|
|
|
|
|
|
|
|
|
|
// 1. Pick a random sound
|
|
|
|
|
AudioClip clip = scaryClips[Random.Range(0, scaryClips.Length)];
|
|
|
|
|
|
|
|
|
|
// 2. Pick a random location (Source)
|
|
|
|
|
AudioSource source = environmentalSources[Random.Range(0, environmentalSources.Length)];
|
|
|
|
|
|
|
|
|
|
// 3. Play
|
|
|
|
|
source.PlayOneShot(clip);
|
|
|
|
|
Debug.Log($"Played sound from: {source.name}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CheckPlayerFacing()
|
|
|
|
|
{
|
|
|
|
|
// (Same logic as before)
|
|
|
|
|
Vector3 stairsDir = transform.forward;
|
|
|
|
|
Vector3 playerDir = playerTransform.forward;
|
|
|
|
|
stairsDir.y = 0; playerDir.y = 0;
|
|
|
|
|
stairsDir.Normalize(); playerDir.Normalize();
|
|
|
|
|
|
|
|
|
|
if (Vector3.Dot(stairsDir, playerDir) < killThreshold)
|
|
|
|
|
{
|
|
|
|
|
TriggerGameOver();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TriggerGameOver()
|
|
|
|
|
{
|
|
|
|
|
isDead = true;
|
|
|
|
|
if (blackScreenPanel != null) blackScreenPanel.SetActive(true);
|
2025-12-04 10:53:21 +00:00
|
|
|
|
2025-12-03 17:23:18 +00:00
|
|
|
// Disable controls
|
|
|
|
|
if (playerTransform.GetComponent<PlayerController>())
|
|
|
|
|
playerTransform.GetComponent<PlayerController>().enabled = false;
|
2025-12-04 10:53:21 +00:00
|
|
|
|
2025-12-03 17:23:18 +00:00
|
|
|
Invoke("RestartLevel", 3f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RestartLevel()
|
|
|
|
|
{
|
|
|
|
|
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OnTriggerEnter(Collider other)
|
|
|
|
|
{
|
|
|
|
|
if (other.CompareTag("Player"))
|
|
|
|
|
{
|
|
|
|
|
playerOnStairs = true;
|
|
|
|
|
playerTransform = other.transform;
|
|
|
|
|
// Reset timer so a sound doesn't play INSTANTLY upon entering
|
|
|
|
|
soundTimer = Random.Range(minSoundDelay, maxSoundDelay);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OnTriggerExit(Collider other)
|
|
|
|
|
{
|
|
|
|
|
if (other.CompareTag("Player")) playerOnStairs = false;
|
|
|
|
|
}
|
|
|
|
|
}
|