Last active
December 9, 2023 18:40
-
-
Save James-Frowen/7c12b1bcbcc1fe358d1b0e89497155c0 to your computer and use it in GitHub Desktop.
Better Toggle group because the built in Toggle group in unity is useless
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// MIT License - Copyright (c) 2023, James Frowen | |
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEngine.UI; | |
public class BetterToggleGroup : MonoBehaviour | |
{ | |
public delegate void ToggleIndexOn(int index); | |
[SerializeField] private int currentValue; | |
[SerializeField] private List<Toggle> toggles; | |
// todo interactable and colors? | |
public event ToggleIndexOn OnChangeValue; | |
private bool hasInit; | |
private bool settingValue; | |
public int Value => currentValue; | |
private void Awake() | |
{ | |
for (var i = 0; i < toggles.Count; i++) | |
{ | |
var toggle = toggles[i]; | |
var index = i; // copy to local variable so that the correct value is captured by action | |
toggle.onValueChanged.AddListener(on => ToggleChanged(on, index)); | |
} | |
} | |
private void Start() | |
{ | |
SetValue(currentValue, false); | |
} | |
private void ToggleChanged(bool on, int i) | |
{ | |
if (settingValue) // dont invoke event if we are inside the SetValue function | |
return; | |
Debug.Assert(on); // should not be setting to false | |
Debug.Assert(currentValue != i); // should not be setting toggle that is the current value | |
SetValue(i, true); | |
} | |
public void SetValue(int value, bool notify) | |
{ | |
if (value >= toggles.Count) | |
throw new System.IndexOutOfRangeException($"Failed to set ToggleGroup to value {value} because there are only {toggles.Count} toggles"); | |
if (hasInit && currentValue == value) // if not init, then call anyway for first setup | |
return; | |
hasInit = true; | |
settingValue = true; | |
currentValue = value; | |
try | |
{ | |
for (var i = 0; i < toggles.Count; i++) | |
{ | |
var toggle = toggles[i]; | |
var nowOn = i == value; | |
toggle.interactable = !nowOn; | |
if (notify) | |
{ | |
toggle.isOn = nowOn; | |
} | |
else | |
{ | |
toggle.SetIsOnWithoutNotify(nowOn); | |
} | |
} | |
} | |
finally | |
{ | |
settingValue = false; | |
} | |
if (notify) | |
{ | |
OnChangeValue.Invoke(value); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment