Skip to content

Instantly share code, notes, and snippets.

@James-Frowen
Last active December 9, 2023 18:40
Show Gist options
  • Save James-Frowen/7c12b1bcbcc1fe358d1b0e89497155c0 to your computer and use it in GitHub Desktop.
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
// 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