189 lines
5.1 KiB
C#
189 lines
5.1 KiB
C#
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using TMPro;
|
|
|
|
public class SimpleDoorInteraction : MonoBehaviour
|
|
{
|
|
[Header("Door Settings")]
|
|
public Transform doorTransform;
|
|
public float openAngle = 90f;
|
|
public float animationSpeed = 2f;
|
|
public KeyCode interactionKey = KeyCode.E;
|
|
|
|
[Header("Detection")]
|
|
public float detectionRadius = 3f;
|
|
public LayerMask playerLayer = -1;
|
|
|
|
[Header("UI")]
|
|
public GameObject promptUI;
|
|
public TextMeshProUGUI promptText;
|
|
|
|
[Header("Audio")]
|
|
public AudioSource audioSource;
|
|
public AudioClip openSound;
|
|
public AudioClip closeSound;
|
|
|
|
[Header("Auto Close")]
|
|
public float autoCloseDelay = 2f;
|
|
|
|
// Public properties for external access
|
|
public bool isOpen { get; private set; } = false;
|
|
public bool isAnimating { get; private set; } = false;
|
|
|
|
private bool playerNearby = false;
|
|
private Vector3 closedRotation;
|
|
private Vector3 openRotation;
|
|
private GameObject player;
|
|
private float autoCloseTimer = 0f;
|
|
|
|
void Start()
|
|
{
|
|
// Find player
|
|
player = GameObject.FindGameObjectWithTag("Player");
|
|
if (player == null)
|
|
{
|
|
Debug.LogWarning("No GameObject with 'Player' tag found. Make sure your player has the 'Player' tag.");
|
|
}
|
|
|
|
// Setup door
|
|
if (doorTransform == null)
|
|
doorTransform = transform;
|
|
|
|
closedRotation = doorTransform.eulerAngles;
|
|
openRotation = closedRotation + new Vector3(0, openAngle, 0);
|
|
|
|
// Hide prompt initially
|
|
if (promptUI != null)
|
|
promptUI.SetActive(false);
|
|
|
|
if (promptText != null)
|
|
promptText.text = $"Press {interactionKey} to open door";
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
CheckPlayerDistance();
|
|
HandleInput();
|
|
HandleDoorAnimation();
|
|
HandleAutoClose();
|
|
}
|
|
|
|
void CheckPlayerDistance()
|
|
{
|
|
if (player == null) return;
|
|
|
|
float distance = Vector3.Distance(transform.position, player.transform.position);
|
|
bool wasNearby = playerNearby;
|
|
playerNearby = distance <= detectionRadius;
|
|
|
|
// Show/hide prompt
|
|
if (playerNearby && !wasNearby)
|
|
{
|
|
ShowPrompt();
|
|
}
|
|
else if (!playerNearby && wasNearby)
|
|
{
|
|
HidePrompt();
|
|
}
|
|
|
|
// Update prompt text based on door state
|
|
if (playerNearby && promptText != null)
|
|
{
|
|
promptText.text = isOpen ? $"Press {interactionKey} to close door" : $"Press {interactionKey} to open door";
|
|
}
|
|
}
|
|
|
|
void HandleInput()
|
|
{
|
|
if (playerNearby && Input.GetKeyDown(interactionKey) && !isAnimating)
|
|
{
|
|
ToggleDoor();
|
|
}
|
|
}
|
|
|
|
void HandleDoorAnimation()
|
|
{
|
|
if (!isAnimating) return;
|
|
|
|
Vector3 targetRotation = isOpen ? openRotation : closedRotation;
|
|
doorTransform.rotation = Quaternion.Slerp(doorTransform.rotation, Quaternion.Euler(targetRotation), animationSpeed * Time.deltaTime);
|
|
|
|
if (Quaternion.Angle(doorTransform.rotation, Quaternion.Euler(targetRotation)) < 0.1f)
|
|
{
|
|
doorTransform.rotation = Quaternion.Euler(targetRotation);
|
|
isAnimating = false;
|
|
}
|
|
}
|
|
|
|
void HandleAutoClose()
|
|
{
|
|
if (isOpen && !isAnimating && !playerNearby)
|
|
{
|
|
autoCloseTimer += Time.deltaTime;
|
|
if (autoCloseTimer >= autoCloseDelay)
|
|
{
|
|
ToggleDoor();
|
|
autoCloseTimer = 0f;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
autoCloseTimer = 0f;
|
|
}
|
|
}
|
|
|
|
public void ToggleDoor()
|
|
{
|
|
isOpen = !isOpen;
|
|
isAnimating = true;
|
|
autoCloseTimer = 0f;
|
|
|
|
// Play sound
|
|
if (audioSource != null)
|
|
{
|
|
AudioClip soundToPlay = isOpen ? openSound : closeSound;
|
|
if (soundToPlay != null)
|
|
audioSource.PlayOneShot(soundToPlay);
|
|
}
|
|
|
|
// Update prompt text
|
|
if (playerNearby && promptText != null)
|
|
{
|
|
promptText.text = isOpen ? $"Press {interactionKey} to close door" : $"Press {interactionKey} to open door";
|
|
}
|
|
}
|
|
|
|
void ShowPrompt()
|
|
{
|
|
if (promptUI != null)
|
|
promptUI.SetActive(true);
|
|
}
|
|
|
|
void HidePrompt()
|
|
{
|
|
if (promptUI != null)
|
|
promptUI.SetActive(false);
|
|
}
|
|
|
|
// Gizmos for visualization in scene view
|
|
void OnDrawGizmosSelected()
|
|
{
|
|
// Draw detection radius
|
|
Gizmos.color = Color.yellow;
|
|
Gizmos.DrawWireSphere(transform.position, detectionRadius);
|
|
|
|
// Draw door swing
|
|
Gizmos.color = Color.green;
|
|
Vector3 doorPos = doorTransform != null ? doorTransform.position : transform.position;
|
|
Vector3 forward = transform.forward;
|
|
|
|
// Closed position
|
|
Gizmos.DrawLine(doorPos, doorPos + forward * 2f);
|
|
|
|
// Open position
|
|
Vector3 openForward = Quaternion.Euler(0, openAngle, 0) * forward;
|
|
Gizmos.color = Color.red;
|
|
Gizmos.DrawLine(doorPos, doorPos + openForward * 2f);
|
|
}
|
|
}
|