Files
HorrorStories/Assets/Scripts/InteractionUI.cs
2026-08-25 16:24:29 +01:00

153 lines
3.9 KiB
C#

using TMPro;
using UnityEngine;
/// <summary>
/// Displays interaction prompts on screen when looking at an IInteractable object.
/// Place this on a UI Canvas with a TextMeshProUGUI or Text component.
/// </summary>
public class InteractionUI : MonoBehaviour
{
[Header("UI References")]
[Tooltip("Text component to display the prompt (e.g. 'Press [Left Click] to Open Door').")]
[SerializeField] private TextMeshProUGUI promptText;
[Tooltip("Optional panel or parent container to hide when not looking at an interactable.")]
[SerializeField] private GameObject promptContainer;
[Tooltip("Optional prefix before the prompt text (e.g. '[L-Click] ').")]
[SerializeField] private string inputHintPrefix = "[L-Click] ";
[Header("Dialogue / Subtitle UI")]
[Tooltip("Optional separate Text component for dialogue/subtitles. If unassigned, promptText is used.")]
[SerializeField] private TextMeshProUGUI dialogueText;
[SerializeField] private GameObject dialogueContainer;
[Header("Player Controller Reference")]
[Tooltip("Reference to the PlayerController. If left empty, it will find the player automatically.")]
[SerializeField] private PlayerController playerController;
public static InteractionUI Instance { get; private set; }
private float dialogueTimer = 0f;
private bool isShowingDialogue = false;
private void Awake()
{
Instance = this;
if (playerController == null)
{
playerController = FindAnyObjectByType<PlayerController>();
}
HidePrompt();
HideDialogue();
}
private void Update()
{
// Handle Dialogue timer
if (isShowingDialogue)
{
dialogueTimer -= Time.deltaTime;
if (dialogueTimer <= 0f)
{
HideDialogue();
}
}
if (playerController == null) return;
// If menu is open, hide the prompt
if (playerController.IsMenuOpen)
{
HidePrompt();
return;
}
IInteractable hovered = playerController.CurrentHoveredInteractable;
if (hovered != null)
{
string prompt = hovered.GetPrompt();
if (!string.IsNullOrEmpty(prompt))
{
ShowPrompt(inputHintPrefix + prompt);
}
else
{
HidePrompt();
}
}
else
{
HidePrompt();
}
}
public void ShowDialogue(string text, float duration = 4f)
{
if (string.IsNullOrEmpty(text)) return;
isShowingDialogue = true;
dialogueTimer = duration;
TextMeshProUGUI targetText = dialogueText != null ? dialogueText : promptText;
GameObject targetContainer = dialogueContainer != null ? dialogueContainer : promptContainer;
if (targetContainer != null)
{
targetContainer.SetActive(true);
}
if (targetText != null)
{
targetText.text = text;
targetText.gameObject.SetActive(true);
}
}
public void HideDialogue()
{
isShowingDialogue = false;
dialogueTimer = 0f;
if (dialogueContainer != null)
{
dialogueContainer.SetActive(false);
}
if (dialogueText != null)
{
dialogueText.gameObject.SetActive(false);
}
}
private void ShowPrompt(string message)
{
if (promptContainer != null)
{
promptContainer.SetActive(true);
}
if (promptText != null)
{
promptText.text = message;
promptText.gameObject.SetActive(true);
}
}
private void HidePrompt()
{
if (promptContainer != null)
{
promptContainer.SetActive(false);
}
if (promptText != null)
{
promptText.gameObject.SetActive(false);
}
}
}