using System.Collections;
|
using System.Collections.Generic;
|
using UnityEngine;
|
using UnityEngine.Events;
|
using UnityEngine.UI;
|
using TMPro;
|
|
public class UIController : MonoBehaviour
|
{
|
[Header("UI Configuration")]
|
[SerializeField] private string uiName = "Generic UI";
|
[SerializeField] private bool closeOnEscapeKey = true;
|
[SerializeField] private bool closeOnInteractKey = true;
|
[SerializeField] private bool pauseGameWhenOpen = false;
|
[SerializeField] private GameObject[] panelsToManage;
|
|
[Header("Animation")]
|
[SerializeField] private bool useAnimation = true;
|
[SerializeField] private float animationDuration = 0.3f;
|
[SerializeField] private Animator uiAnimator;
|
|
[Header("UI Elements")]
|
[SerializeField] private Button closeButton;
|
[SerializeField] private TextMeshProUGUI titleText;
|
[SerializeField] private TextMeshProUGUI descriptionText;
|
|
[Header("Events")]
|
public UnityEvent OnUIOpenedEvent = new UnityEvent();
|
public UnityEvent OnUIClosedEvent = new UnityEvent();
|
|
// Current state tracking
|
private bool isOpen = false;
|
private string currentType = "";
|
private GameObject interactionSource;
|
private KeyCode? interactKey;
|
|
private void Awake()
|
{
|
// Set up close button if available
|
if (closeButton != null)
|
{
|
closeButton.onClick.AddListener(CloseUI);
|
}
|
|
// Initial state is closed
|
//gameObject.SetActive(false);
|
}
|
|
private void OnEnable()
|
{
|
// Set UI as open
|
isOpen = true;
|
|
// Pause game if configured to do so
|
if (pauseGameWhenOpen)
|
{
|
GameManager.PauseGame();
|
}
|
|
if (closeOnInteractKey)
|
{
|
interactKey = FindAnyObjectByType<PlayerInteraction>().interactKey;
|
}
|
|
// Invoke open event
|
OnUIOpenedEvent.Invoke();
|
|
// Play open animation if using an animator
|
if (useAnimation && uiAnimator != null)
|
{
|
uiAnimator.SetTrigger("Open");
|
}
|
}
|
|
private void Update()
|
{
|
// Check for escape key to close UI
|
if (isOpen && (closeOnEscapeKey && Input.GetKeyDown(KeyCode.Escape) || (closeOnInteractKey && interactKey.HasValue && Input.GetKeyDown(interactKey.Value))))
|
{
|
CloseUI();
|
}
|
}
|
|
/// <summary>
|
/// Called when this UI is opened by an interactable
|
/// </summary>
|
/// <param name="type">The type of interaction that opened this UI</param>
|
/// <param name="source">Reference to the GameObject that triggered the interaction</param>
|
public virtual void OnUIOpened(string type, GameObject source)
|
{
|
currentType = type;
|
interactionSource = source;
|
|
// Update UI elements based on type
|
UpdateUIElements();
|
|
// Activate the appropriate panel if we have multiple
|
ActivateRelevantPanel(type);
|
}
|
|
/// <summary>
|
/// Close the UI
|
/// </summary>
|
public virtual void CloseUI()
|
{
|
// If using animation, trigger close animation and wait before disabling
|
if (useAnimation && uiAnimator != null)
|
{
|
uiAnimator.SetTrigger("Close");
|
StartCoroutine(CloseAfterAnimation());
|
}
|
else
|
{
|
// Otherwise close immediately
|
FinalizeClose();
|
}
|
}
|
|
private IEnumerator CloseAfterAnimation()
|
{
|
yield return new WaitForSecondsRealtime(animationDuration);
|
FinalizeClose();
|
}
|
|
private void FinalizeClose()
|
{
|
// Restore time scale if it was changed
|
if (pauseGameWhenOpen)
|
{
|
GameManager.ResumeGame();
|
}
|
|
// Set state to closed
|
isOpen = false;
|
|
// Invoke closed event
|
OnUIClosedEvent.Invoke();
|
|
// Disable gameObject
|
gameObject.SetActive(false);
|
}
|
|
/// <summary>
|
/// Updates UI elements like title and description based on the interaction type
|
/// </summary>
|
protected virtual void UpdateUIElements()
|
{
|
// Set title if available
|
if (titleText != null)
|
{
|
titleText.text = GetTitleForType(currentType);
|
}
|
|
// Set description if available
|
if (descriptionText != null)
|
{
|
descriptionText.text = GetDescriptionForType(currentType);
|
}
|
}
|
|
/// <summary>
|
/// Gets the appropriate title based on interaction type
|
/// Override this in derived classes for specific implementations
|
/// </summary>
|
protected virtual string GetTitleForType(string type)
|
{
|
return uiName;
|
}
|
|
/// <summary>
|
/// Gets the appropriate description based on interaction type
|
/// Override this in derived classes for specific implementations
|
/// </summary>
|
protected virtual string GetDescriptionForType(string type)
|
{
|
return "";
|
}
|
|
/// <summary>
|
/// Activates the relevant panel based on the interaction type
|
/// </summary>
|
protected virtual void ActivateRelevantPanel(string type)
|
{
|
// If we have multiple panels, we can selectively enable them
|
// This is a simple implementation, you might want to expand this
|
// with a dictionary or switch statement for more complex UIs
|
if (panelsToManage != null && panelsToManage.Length > 0)
|
{
|
// Default behavior: activate the first panel
|
foreach (var panel in panelsToManage)
|
{
|
panel.SetActive(panel == panelsToManage[0]);
|
}
|
}
|
}
|
|
/// <summary>
|
/// Get the GameObject that triggered this UI to open
|
/// </summary>
|
protected GameObject GetInteractionSource()
|
{
|
return interactionSource;
|
}
|
|
/// <summary>
|
/// Get the current interaction type
|
/// </summary>
|
protected string GetCurrentType()
|
{
|
return currentType;
|
}
|
|
/// <summary>
|
/// Check if the UI is currently open
|
/// </summary>
|
public bool IsOpen()
|
{
|
return isOpen;
|
}
|
}
|