Files
Stair_Horror/Assets/Scripts/FrontDoorEvent.cs

165 lines
4.8 KiB
C#

using UnityEngine;
using System.Collections;
public class FrontDoorEvent : MonoBehaviour, IInteractable
{
[Header("Door Settings")]
public float openAngle = 90f;
public float smoothSpeed = 2f;
[Header("Audio Clips")]
public AudioSource doorSource;
public AudioClip doorbellClip;
public AudioClip voiceClip; // <--- NEW: The voice line
[Tooltip("IMPORTANT: This must be a SINGLE knock sound, not a loop!")]
public AudioClip singleKnockClip;
public AudioClip doorOpenSound;
// windSound is removed
[Header("Timeline Settings")]
public float timeBeforeVoice = 3f; // Ring for 3 seconds
public float timeAfterVoice = 3f; // Ring for 3 seconds AFTER voice, then knock
[Header("Knocking Settings")]
[Range(0.1f, 1f)] public float heavyPitch = 0.8f;
public float totalKnockingDuration = 8f;
public float startDelay = 1.0f;
public float endDelay = 0.1f;
// State
private bool isOpen = false;
private bool eventActive = false;
private Quaternion initialRotation;
private Quaternion targetRotation;
void Start()
{
initialRotation = transform.localRotation;
targetRotation = initialRotation;
if(GameManager.Instance != null) GameManager.Instance.frontDoor = this;
}
void Update()
{
transform.localRotation = Quaternion.Slerp(transform.localRotation, targetRotation, Time.deltaTime * smoothSpeed);
}
public void TriggerEvent()
{
if(eventActive || isOpen) return;
eventActive = true;
StartCoroutine(TheHauntingSequence());
}
IEnumerator TheHauntingSequence()
{
// --- PHASE 1: INITIAL RINGING ---
doorSource.pitch = 1f;
doorSource.volume = 0.5f;
doorSource.clip = doorbellClip;
doorSource.loop = true;
doorSource.Play();
// Wait...
float timer = 0f;
while (timer < timeBeforeVoice && !isOpen)
{
timer += Time.deltaTime;
yield return null;
}
if (isOpen) yield break;
// --- PHASE 2: THE VOICE ---
if (voiceClip != null)
{
doorSource.Stop(); // Cut the bell
doorSource.loop = false;
// Play Voice
doorSource.PlayOneShot(voiceClip);
// Wait for the exact length of the voice clip
float voiceTimer = 0f;
while (voiceTimer < voiceClip.length && !isOpen)
{
voiceTimer += Time.deltaTime;
yield return null;
}
}
if (isOpen) yield break;
// --- PHASE 3: RESUME RINGING ---
doorSource.clip = doorbellClip;
doorSource.loop = true;
doorSource.Play();
timer = 0f;
while (timer < timeAfterVoice && !isOpen)
{
timer += Time.deltaTime;
yield return null;
}
if (isOpen) yield break;
// --- PHASE 4: AGGRESSIVE KNOCKING (The Drummer Method) ---
doorSource.Stop();
doorSource.loop = false;
doorSource.pitch = heavyPitch; // Drop pitch for bass
float knockTimer = 0f;
while (knockTimer < totalKnockingDuration && !isOpen)
{
float progress = knockTimer / totalKnockingDuration;
// Volume Up
float currentVol = Mathf.Lerp(0.4f, 1f, progress);
doorSource.PlayOneShot(singleKnockClip, currentVol);
// Speed Up (Reduce Delay)
float currentDelay = Mathf.Lerp(startDelay, endDelay, progress);
// Wait for delay
float subTimer = 0f;
while(subTimer < currentDelay)
{
subTimer += Time.deltaTime;
knockTimer += Time.deltaTime;
if(isOpen) yield break;
yield return null;
}
}
// --- PHASE 5: SILENCE ---
Debug.Log("Knocking finished. Dead silence.");
}
public void Interact()
{
if (isOpen) return;
// Player Opened the Door!
isOpen = true;
eventActive = false;
// Open Visuals
targetRotation = initialRotation * Quaternion.Euler(0, openAngle, 0);
// Audio Reset
doorSource.Stop();
doorSource.pitch = 1f;
doorSource.volume = 1f;
// Just play the open sound, NO wind following it
doorSource.PlayOneShot(doorOpenSound);
// Trigger Nightmare Mode
if(GameManager.Instance != null) GameManager.Instance.TriggerNightmareMode();
}
public string GetDescription()
{
if (eventActive) return "Press [E] to <color=red>Check Noise</color>";
return isOpen ? "" : "Press [E] to Open";
}
}