Files
beyond/Assets/Scripts/QuestMachineDerivatives/bUnityUIQuestHUDToggleButtonController.cs

177 lines
5.3 KiB
C#

using System;
using System.Collections;
using PixelCrushers;
using PixelCrushers.QuestMachine;
using TMPro; // Import TextMeshPro namespace
using UnityEngine;
using UnityEngine.UI;
namespace Beyond
{
[RequireComponent(typeof(Button))]
[RequireComponent(typeof(Image))]
public class bUnityUIQuestHUDToggleButtonController : MonoBehaviour, IMessageHandler
{
[SerializeField] private Sprite m_openSprite;
[SerializeField] private Sprite m_closedSprite;
[SerializeField] private string m_openText = "Open"; // Text to display when open
[SerializeField] private string m_closedText = "Closed"; // Text to display when closed
[SerializeField] private TextMeshProUGUI m_textMeshPro; // Reference to the TextMeshPro component
[SerializeField] private UIPanel m_UIPanel;
[SerializeField] private float m_autoHideTime = 10f;
[SerializeField] private bool m_autoHide = false;
private Image m_buttonImage;
private MenuScroll m_menuScroll;
private Coroutine m_hiddingCoroutine = null;
private void Awake()
{
m_buttonImage = GetComponent<Image>();
}
private void Start()
{
MessageSystem.AddListener(this, QuestMachineMessages.QuestStateChangedMessage, string.Empty);
m_menuScroll = FindObjectOfType<MenuScroll>();
if (m_menuScroll != null)
{
m_menuScroll.OnOpened += DisableButtonImage;
m_menuScroll.OnClosed += EnableButtonImage;
}
if (m_UIPanel != null)
{
m_UIPanel.onOpen.AddListener(OnOpen);
m_UIPanel.onClose.AddListener(OnClose);
}
}
private void OnEnable()
{
TryToStartAutohideCoroutine();
}
private void OnDestroy()
{
MessageSystem.RemoveListener(this, QuestMachineMessages.QuestStateChangedMessage, string.Empty);
if (m_menuScroll != null)
{
m_menuScroll.OnOpened -= DisableButtonImage;
m_menuScroll.OnClosed -= EnableButtonImage;
}
if (m_UIPanel != null && m_UIPanel.gameObject != null)
{
m_UIPanel.onOpen.RemoveListener(OnOpen);
m_UIPanel.onClose.RemoveListener(OnClose);
}
}
public void OnMessage(MessageArgs messageArgs)
{
// Optional but recommended: check if active before processing message
if (!gameObject.activeInHierarchy) return;
switch (messageArgs.message)
{
case QuestMachineMessages.QuestStateChangedMessage:
if ((QuestState)messageArgs.values[1] == QuestState.Active)
{
if (m_UIPanel != null)
{
m_UIPanel.Close();
m_UIPanel.Open();
}
// The OnOpen listener will call TryToStartAutohideCoroutine
}
break;
}
}
private void SetImageToOpen()
{
m_buttonImage.sprite = m_openSprite;
if (m_textMeshPro != null)
{
m_textMeshPro.text = m_openText;
}
}
private void SetImageToClosed()
{
m_buttonImage.sprite = m_closedSprite;
if (m_textMeshPro != null)
{
m_textMeshPro.text = m_closedText;
}
}
private void DisableButtonImage()
{
if (m_buttonImage == null) return;
m_buttonImage.enabled = false;
}
private void EnableButtonImage()
{
if (m_buttonImage == null) return;
m_buttonImage.enabled = true;
}
private IEnumerator COR_AutoHide()
{
yield return new WaitForSeconds(m_autoHideTime);
if (m_UIPanel != null)
{
m_UIPanel.Close();
}
m_hiddingCoroutine = null;
}
private void OnClose()
{
// Stop the coroutine if the panel is closed manually
if (m_hiddingCoroutine != null)
{
StopCoroutine(m_hiddingCoroutine);
m_hiddingCoroutine = null;
}
SetImageToClosed();
}
private void OnOpen()
{
SetImageToOpen();
TryToStartAutohideCoroutine();
}
private void TryToStartAutohideCoroutine()
{
// FIX: Check if the GameObject is active before starting a coroutine.
// This prevents the "Coroutine couldn't be started" error.
if (!gameObject.activeInHierarchy)
{
return;
}
if (!m_autoHide)
{
return;
}
// Stop any previously running hide coroutine to reset the timer
if (m_hiddingCoroutine != null)
{
StopCoroutine(m_hiddingCoroutine);
}
// This is line 139 from your original script
m_hiddingCoroutine = StartCoroutine(COR_AutoHide());
}
}
}