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().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(); } } /// /// Called when this UI is opened by an interactable /// /// The type of interaction that opened this UI /// Reference to the GameObject that triggered the interaction 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); } /// /// Close the UI /// 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); } /// /// Updates UI elements like title and description based on the interaction type /// 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); } } /// /// Gets the appropriate title based on interaction type /// Override this in derived classes for specific implementations /// protected virtual string GetTitleForType(string type) { return uiName; } /// /// Gets the appropriate description based on interaction type /// Override this in derived classes for specific implementations /// protected virtual string GetDescriptionForType(string type) { return ""; } /// /// Activates the relevant panel based on the interaction type /// 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]); } } } /// /// Get the GameObject that triggered this UI to open /// protected GameObject GetInteractionSource() { return interactionSource; } /// /// Get the current interaction type /// protected string GetCurrentType() { return currentType; } /// /// Check if the UI is currently open /// public bool IsOpen() { return isOpen; } }