using UnityEngine; public class DoorController : MonoBehaviour, IInteractable { [Header("Movement Settings")] public float openAngle = 90f; // How far the door swings (usually 90 or -90) public float smoothSpeed = 2f; // How fast it opens private bool isOpen = false; [Header("Horror Mechanics")] [Range(0f, 1f)] public float stuckChance = 0.1f; // 10% chance to fail public float rattleStrength = 5f; // How much it shakes if stuck [Header("Audio")] public AudioSource audioSource; public AudioClip openSound; public AudioClip closeSound; public AudioClip stuckSound; // Sound of handle jiggling or locked thud // Internal State private Quaternion initialRotation; private Quaternion targetRotation; void Start() { // Remember how the door was rotated at the start initialRotation = transform.localRotation; targetRotation = initialRotation; // Auto-fetch audio source if missed if (audioSource == null) audioSource = GetComponent(); } void Update() { // Smoothly rotate the door towards the target rotation every frame transform.localRotation = Quaternion.Slerp(transform.localRotation, targetRotation, Time.deltaTime * smoothSpeed); } public void Interact() { // 1. Calculate "Stuck" Mechanic // Only checking stuck chance if we are trying to OPEN it (closing usually doesn't jam) if (!isOpen && Random.value < stuckChance) { PlaySound(stuckSound); // Optional: Add a tiny visual "shake" here if you want advanced polish return; } // 2. Toggle State isOpen = !isOpen; // 3. Set Target Rotation if (isOpen) { // Calculate rotation based on the openAngle targetRotation = initialRotation * Quaternion.Euler(0, openAngle, 0); PlaySound(openSound); } else { // Return to start targetRotation = initialRotation; PlaySound(closeSound); } } void PlaySound(AudioClip clip) { if (audioSource != null && clip != null) { audioSource.PlayOneShot(clip); } } public string GetDescription() { if (isOpen) return "Press [E] to Close"; else return "Press [E] to Open"; } }