using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; using System.Collections; using System.Collections.Generic; public class selectSettingsOptions : MonoBehaviour { [Header("esc")] public Button escButton; public GameObject selfGO; [Header("Inspector")] public Button userSettingsButton; public GameObject userSettingsGameObject; public Image userSettings_selectedMark; [Header("Inspector")] public Button graphicSettingsButton; public GameObject graphicSettingsGameObject; public Image graphicSettings_selectedMark; [Header("Inspector")] public Button audioSettingsButton; public GameObject audioSettingsGameObject; public Image audioSettings_selectedMark; [Header("Inspector")] public Button controlSettingsButton; public GameObject controlSettingsGameObject; public Image controlSettings_selectedMark; [Header("Inspector")] public Button gameSettingsButton; public GameObject gameSettingsGameObject; public Image gameSettings_selectedMark; [Header("Inspector")] public Button aboutUsButton; public GameObject aboutUsGameObject; public Image aboutUs_selectedMark; [Header("Inspector")] public Button deviceInfoButton; public GameObject deviceInfoGameObject; public Image deviceInfo_selectedMark; [Header("Fade Settings")] [Tooltip("Hover alpha when mouse over (0-1).")] [Range(0f, 1f)] public float hoverAlpha = 0.75f; [Tooltip("Selected mark alpha when option is selected (0-1).")] [Range(0f, 1f)] public float selectedAlpha = 1f; [Tooltip("Fade duration in seconds.")] [Min(0f)] public float fadeDuration = 0.1f; // internal state private class OptionEntry { public Button button; public GameObject panel; public Image mark; public Coroutine fadeCoroutine; public bool selected; } private List options = new List(); private OptionEntry currentSelected = null; void Awake() { options.Clear(); AddOption(userSettingsButton, userSettingsGameObject, userSettings_selectedMark); AddOption(graphicSettingsButton, graphicSettingsGameObject, graphicSettings_selectedMark); AddOption(audioSettingsButton, audioSettingsGameObject, audioSettings_selectedMark); AddOption(controlSettingsButton, controlSettingsGameObject, controlSettings_selectedMark); AddOption(gameSettingsButton, gameSettingsGameObject, gameSettings_selectedMark); AddOption(aboutUsButton, aboutUsGameObject, aboutUs_selectedMark); AddOption(deviceInfoButton, deviceInfoGameObject, deviceInfo_selectedMark); } void Start() { // default select userSettings if (userSettingsButton != null) SelectOptionByButton(userSettingsButton); // listen for esc to close this panel if active if (escButton != null && selfGO != null) { escButton.onClick.AddListener(OnEscButtonClicked); } } void OnDestroy() { foreach (var opt in options) { if (opt.button != null) opt.button.onClick.RemoveAllListeners(); RemoveEventTrigger(opt.button); } if (escButton != null && selfGO != null) { escButton.onClick.RemoveListener(OnEscButtonClicked); } } private void OnEscButtonClicked() { if (selfGO != null && selfGO.activeSelf) { selfGO.SetActive(false); } } void AddOption(Button btn, GameObject panel, Image mark) { var entry = new OptionEntry { button = btn, panel = panel, mark = mark, selected = false, fadeCoroutine = null }; options.Add(entry); if (btn != null) { btn.onClick.AddListener(() => OnOptionClicked(entry)); EnsureEventTrigger(btn, entry); } if (mark != null) { var c = mark.color; c.a = 0f; mark.color = c; mark.enabled = false; } if (panel != null) panel.SetActive(false); } void EnsureEventTrigger(Button btn, OptionEntry entry) { if (btn == null) return; EventTrigger trig = btn.GetComponent(); if (trig == null) trig = btn.gameObject.AddComponent(); // pointer enter var entryEnter = new EventTrigger.Entry { eventID = EventTriggerType.PointerEnter }; entryEnter.callback.AddListener((data) => { OnOptionPointerEnter(entry); }); trig.triggers.Add(entryEnter); // pointer exit var entryExit = new EventTrigger.Entry { eventID = EventTriggerType.PointerExit }; entryExit.callback.AddListener((data) => { OnOptionPointerExit(entry); }); trig.triggers.Add(entryExit); } void RemoveEventTrigger(Button btn) { if (btn == null) return; var trig = btn.GetComponent(); if (trig != null) Destroy(trig); } void OnOptionPointerEnter(OptionEntry entry) { if (entry == null) return; if (entry.selected) return; StartFade(entry, hoverAlpha); } void OnOptionPointerExit(OptionEntry entry) { if (entry == null) return; if (entry.selected) return; StartFade(entry, 0f); } void OnOptionClicked(OptionEntry entry) { if (entry == null) return; SelectEntry(entry); } void SelectOptionByButton(Button btn) { var entry = options.Find(o => o.button == btn); if (entry != null) SelectEntry(entry); } void SelectEntry(OptionEntry entry) { if (entry == null) return; if (currentSelected != null && currentSelected != entry) { currentSelected.selected = false; StartFade(currentSelected, 0f); if (currentSelected.panel != null) currentSelected.panel.SetActive(false); } currentSelected = entry; currentSelected.selected = true; if (currentSelected.panel != null) currentSelected.panel.SetActive(true); StartFade(currentSelected, selectedAlpha); } void StartFade(OptionEntry entry, float targetAlpha) { if (entry == null || entry.mark == null) return; entry.mark.enabled = true; if (entry.fadeCoroutine != null) StopCoroutine(entry.fadeCoroutine); entry.fadeCoroutine = StartCoroutine(FadeImage(entry.mark, targetAlpha, fadeDuration, () => { if (Mathf.Approximately(targetAlpha, 0f)) { if (!entry.selected) entry.mark.enabled = false; } })); } IEnumerator FadeImage(Image img, float targetAlpha, float duration, System.Action onComplete = null) { if (img == null) yield break; float start = img.color.a; float t = 0f; while (t < duration) { t += Time.unscaledDeltaTime; float a = Mathf.Lerp(start, targetAlpha, duration <= 0f ? 1f : (t / duration)); var c = img.color; c.a = a; img.color = c; yield return null; } var fc = img.color; fc.a = targetAlpha; img.color = fc; onComplete?.Invoke(); } }