Files

247 lines
7.3 KiB
C#

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<OptionEntry> options = new List<OptionEntry>();
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<EventTrigger>();
if (trig == null) trig = btn.gameObject.AddComponent<EventTrigger>();
// 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<EventTrigger>();
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();
}
}