Skip to content

Commit 7e58f3c

Browse files
Update UITutorialManager.cs
Updated tutorial manager to avoid overriding event listeners on your existing buttons. It just adds events without intefering with how your buttons function
1 parent 5ac6e60 commit 7e58f3c

1 file changed

Lines changed: 114 additions & 34 deletions

File tree

TutorialSystem/Manager/UITutorialManager.cs

Lines changed: 114 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public class UITutorialManager : MonoBehaviour
1717
private Action currentlyFocusedButtonCallback; // Callback for the currently focused button
1818
private GameObject currentTooltip; // The currently active tooltip
1919
private TooltipUI tooltip;
20+
private Button overlayButton;
2021

2122
[Header("Debug")]
2223
public SequenceID testSequenceID;
@@ -25,6 +26,7 @@ public class UITutorialManager : MonoBehaviour
2526
public int currentStepIndex = 0;
2627
private TutorialSequence currentSequence;
2728
private Dictionary<ButtonID, UIButton> buttonDictionary = new Dictionary<ButtonID, UIButton>();
29+
private Dictionary<Button, UnityEngine.Events.UnityAction> tutorialClickActions = new();
2830

2931
void Awake()
3032
{
@@ -44,6 +46,7 @@ private void CacheAllButtons()
4446
buttonDictionary[button.buttonID] = button;
4547
}
4648
}
49+
ResetButtonAction();
4750
}
4851

4952
[Button]
@@ -84,44 +87,78 @@ public void FocusOnNextButton()
8487

8588
var step = currentSequence.steps[currentStepIndex];
8689

87-
// Enable overlay panel
88-
if (overlayPanel != null) overlayPanel.SetActive(true);
89-
90-
// Find target button
91-
UIButton targetButton = FindButton(step.buttonID);
92-
if (targetButton == null)
90+
// Enable overlay panel ad add a button to it for skipping panels without buttons
91+
if (overlayPanel != null)
9392
{
94-
Debug.LogError($"Button with ID {step.buttonID} not found!");
95-
return;
93+
overlayPanel.SetActive(true);
94+
if (overlayPanel.GetComponent<Button>() == null)
95+
{
96+
overlayButton = overlayPanel.AddComponent<Button>();
97+
}
98+
else
99+
{
100+
overlayButton = overlayPanel.GetComponent<Button>();
101+
}
102+
overlayButton.interactable = false;
96103
}
97104

98-
// Activate parent if it's inactive
99-
if (!targetButton.gameObject.activeInHierarchy)
105+
// Find target button
106+
if (step.focusButtonID != ButtonID.None)
100107
{
101-
Transform parent = targetButton.transform.parent;
102-
while (parent != null)
108+
UIButton targetButton = FindButton(step.focusButtonID);
109+
if (targetButton == null)
110+
{
111+
Debug.LogError($"Button with ID {step.focusButtonID} not found!");
112+
return;
113+
}
114+
115+
// Activate parent if it's inactive
116+
if (!targetButton.gameObject.activeInHierarchy)
103117
{
104-
if (!parent.gameObject.activeSelf)
118+
Transform parent = targetButton.transform.parent;
119+
while (parent != null)
105120
{
106-
parent.gameObject.SetActive(true);
121+
if (!parent.gameObject.activeSelf)
122+
{
123+
parent.gameObject.SetActive(true);
124+
}
125+
parent = parent.parent;
107126
}
108-
parent = parent.parent;
109127
}
110-
}
111128

112-
// Highlight button
113-
OnButtonFocus?.Invoke(step.buttonID);
129+
// Highlight button
130+
OnButtonFocus?.Invoke(step.focusButtonID);
131+
132+
// Get the Button component and remove any previous listeners to avoid stacking events
133+
Button buttonComponent = targetButton.GetComponent<Button>();
134+
if (tutorialClickActions.TryGetValue(buttonComponent, out var existingAction))
135+
{
136+
buttonComponent.onClick.RemoveListener(existingAction);
137+
tutorialClickActions.Remove(buttonComponent);
138+
}
139+
140+
// Create a new action for this step
141+
UnityEngine.Events.UnityAction clickAction = () => OnStepCompleted(step);
142+
143+
// Add and store it
144+
buttonComponent.onClick.AddListener(clickAction);
145+
tutorialClickActions[buttonComponent] = clickAction;
146+
}
147+
else
148+
{
149+
// Move to next step when we tap on the overlay panel
150+
if (overlayButton)
151+
{
152+
overlayButton.interactable = true;
153+
overlayButton.onClick.RemoveAllListeners(); // Add this before adding new one
154+
overlayButton.onClick.AddListener(() => OnStepCompleted(step));
155+
}
156+
}
114157

115158
// Show tooltip
116-
ShowTooltip(step.buttonID, step.message);
117-
118-
// Get the Button component and remove any previous listeners to avoid stacking events
119-
Button buttonComponent = targetButton.GetComponent<Button>();
120-
buttonComponent.onClick.RemoveAllListeners(); // Remove previous tutorial event listeners
121-
buttonComponent.onClick.AddListener(() => OnStepCompleted(step)); // Move to next step on click
159+
ShowTooltip(step.focusButtonID, step.message);
122160
}
123161

124-
125162
// Called when a tutorial step is completed
126163
private void OnStepCompleted(UITutorialStep step)
127164
{
@@ -136,6 +173,7 @@ public void EndTutorial()
136173
isTutorialActive = false;
137174
if (overlayPanel != null) overlayPanel.SetActive(false);
138175
Debug.Log("Tutorial Completed.");
176+
ResetButtonAction();
139177
}
140178

141179
// Focus on a specific button by its ButtonID and provide a callback for when it's clicked
@@ -168,18 +206,50 @@ private void ShowTooltip(ButtonID buttonID, string tooltipText)
168206
currentTooltip = Instantiate(tooltipPrefab, overlayPanel.transform);
169207
tooltip = currentTooltip.GetComponent<TooltipUI>();
170208
}
209+
else
210+
{
211+
tooltip.gameObject.SetActive(false);
212+
}
171213

172214
// Find the target button
173-
UIButton targetButton = FindButton(buttonID);
174-
if (targetButton == null)
215+
if (buttonID != ButtonID.None)
175216
{
176-
Debug.LogError($"Button with ID {buttonID} not found!");
177-
return;
178-
}
217+
UIButton targetButton = FindButton(buttonID);
218+
if (targetButton == null)
219+
{
220+
Debug.LogError($"Button with ID {buttonID} not found!");
221+
return;
222+
}
179223

180-
// Set tooltip text and position
224+
// Set tooltip position
225+
PositionNearButton(targetButton.GetComponent<RectTransform>());
226+
}
227+
else
228+
{
229+
// Set tooltip position to the center of the screen
230+
PositionAtCenter();
231+
}
181232
tooltip.SetText(tooltipText);
182-
PositionNearButton(targetButton.GetComponent<RectTransform>());
233+
tooltip.gameObject.SetActive(true);
234+
}
235+
236+
private void PositionAtCenter()
237+
{
238+
RectTransform toolTipRect = tooltip.GetComponent<RectTransform>();
239+
240+
// Ensure the tooltip anchors and pivot are centered
241+
toolTipRect.anchorMin = new Vector2(0.5f, 0.5f);
242+
toolTipRect.anchorMax = new Vector2(0.5f, 0.5f);
243+
toolTipRect.pivot = new Vector2(0.5f, 0.5f);
244+
245+
// Center it relative to the parent (canvas/overlayPanel)
246+
toolTipRect.anchoredPosition = Vector2.zero;
247+
248+
// Hide arrow if it exists
249+
if (tooltip.arrowImage != null)
250+
{
251+
tooltip.arrowImage.gameObject.SetActive(false);
252+
}
183253
}
184254

185255
public void PositionNearButton(RectTransform targetButtonRect)
@@ -229,11 +299,11 @@ public void PositionNearButton(RectTransform targetButtonRect)
229299

230300
// Apply tooltip position
231301
toolTipRect.anchoredPosition = new Vector2(desiredX, desiredY);
232-
toolTipRect.gameObject.SetActive(true);
233302

234303
// Position arrow
235304
if (tooltip.arrowImage != null)
236305
{
306+
tooltip.arrowImage.gameObject.SetActive(true);
237307
RectTransform arrowRect = tooltip.arrowImage;
238308

239309
// Calculate horizontal offset to maintain arrow pointing at button
@@ -264,6 +334,7 @@ public void PositionNearButton(RectTransform targetButtonRect)
264334
}
265335
}
266336
}
337+
267338
// Call this method to stop focusing on any button
268339
public void StopFocus()
269340
{
@@ -312,4 +383,13 @@ private UIButton FindButton(ButtonID id)
312383
}
313384
return null; // Button not found
314385
}
315-
}
386+
387+
void ResetButtonAction()
388+
{
389+
foreach (var pair in tutorialClickActions)
390+
{
391+
pair.Key.onClick.RemoveListener(pair.Value);
392+
}
393+
tutorialClickActions.Clear();
394+
}
395+
}

0 commit comments

Comments
 (0)