miepzerino
2025-04-08 40ac185dc7a017d95771fe580c77eab20e663908
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
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;
    }
}