Skip to content

Instantly share code, notes, and snippets.

@antont
Created November 11, 2017 21:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save antont/672c5281814575d80167a857b97f02d4 to your computer and use it in GitHub Desktop.
Save antont/672c5281814575d80167a857b97f02d4 to your computer and use it in GitHub Desktop.
Unity: Toggle3D and ToggleGroup3D, for selecting 3D objects similarily to how Unity.UI Toggles and ToggleGroup works. Ported from those counterparts.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Toggle3D : MonoBehaviour {
// group that this toggle can belong to
[SerializeField]
private ToggleGroup3D m_Group;
[Tooltip("Is the toggle currently on or off?")]
[SerializeField]
private bool m_IsOn;
public ToggleGroup3D group
{
get { return m_Group; }
set
{
m_Group = value;
#if UNITY_EDITOR
if (Application.isPlaying)
#endif
{
SetToggleGroup(m_Group, true);
//PlayEffect(true);
}
}
}
// Use this for initialization
void Start () {
SetToggleGroup(m_Group, false);
}
// Update is called once per frame
void Update () {
}
void OnMouseDown()
{
isOn = !isOn;
}
void ToggleHighlight(bool enable)
{
GameObject hilite = transform.Find("highlight").gameObject;
hilite.SetActive(enable);
}
/// <summary>
/// Whether the toggle is currently active.
/// </summary>
public bool isOn
{
get { return m_IsOn; }
set
{
Set(value);
}
}
void Set(bool value)
{
Set(value, true);
}
void Set(bool value, bool sendCallback)
{
if (m_IsOn == value)
return;
ToggleHighlight(value);
// if we are in a group and set to true, do group logic
m_IsOn = value;
if (m_Group != null && IsActive())
{
if (m_IsOn || (!m_Group.AnyTogglesOn() && !m_Group.allowSwitchOff))
{
m_IsOn = true;
m_Group.NotifyToggleOn(this);
}
}
}
private void SetToggleGroup(ToggleGroup3D newGroup, bool setMemberValue)
{
ToggleGroup3D oldGroup = m_Group;
// Sometimes IsActive returns false in OnDisable so don't check for it.
// Rather remove the toggle too often than too little.
if (m_Group != null)
m_Group.UnregisterToggle(this);
// At runtime the group variable should be set but not when calling this method from OnEnable or OnDisable.
// That's why we use the setMemberValue parameter.
if (setMemberValue)
m_Group = newGroup;
// Only register to the new group if this Toggle is active.
if (newGroup != null && IsActive())
newGroup.RegisterToggle(this);
// If we are in a new group, and this toggle is on, notify group.
// Note: Don't refer to m_Group here as it's not guaranteed to have been set.
if (newGroup != null && newGroup != oldGroup && isOn && IsActive())
newGroup.NotifyToggleOn(this);
}
/* no OnEnable here, is it a GUI thing or what?
protected override void OnEnable()
{
base.OnEnable();
SetToggleGroup(m_Group, false);
//PlayEffect(true);
}
protected override void OnDisable()
{
SetToggleGroup(null, false);
base.OnDisable();
}*/
private bool IsActive()
{
return gameObject.activeSelf;
}
}
using System;
using System.Linq;
using System.Collections.Generic;
using UnityEngine;
//adapted from https://bitbucket.org/Unity-Technologies/ui/src/6a975b5d7ec71f5cf99b615bc31d1d14e6e246db/UnityEngine.UI/UI/Core/ToggleGroup.cs?at=2017.1&fileviewer=file-view-default
//it's kind of sad that due to the type system, original ToggleGroup can not be used for 3D toggles, even though the logic is exactly same
[DisallowMultipleComponent]
public class ToggleGroup3D : MonoBehaviour
{
[SerializeField] private bool m_AllowSwitchOff = false;
public bool allowSwitchOff { get { return m_AllowSwitchOff; } set { m_AllowSwitchOff = value; } }
private List<Toggle3D> m_Toggles = new List<Toggle3D>();
protected ToggleGroup3D()
{ }
private void ValidateToggleIsInGroup(Toggle3D toggle)
{
if (toggle == null || !m_Toggles.Contains(toggle))
throw new ArgumentException(string.Format("Toggle {0} is not part of ToggleGroup {1}", new object[] { toggle, this }));
}
public void NotifyToggleOn(Toggle3D toggle)
{
ValidateToggleIsInGroup(toggle);
// disable all toggles in the group
for (var i = 0; i < m_Toggles.Count; i++)
{
if (m_Toggles[i] == toggle)
continue;
m_Toggles[i].isOn = false;
}
}
public void UnregisterToggle(Toggle3D toggle)
{
if (m_Toggles.Contains(toggle))
m_Toggles.Remove(toggle);
}
public void RegisterToggle(Toggle3D toggle)
{
if (!m_Toggles.Contains(toggle))
m_Toggles.Add(toggle);
}
public bool AnyTogglesOn()
{
return m_Toggles.Find(x => x.isOn) != null;
}
public IEnumerable<Toggle3D> ActiveToggles()
{
return m_Toggles.Where(x => x.isOn);
}
public void SetAllTogglesOff()
{
bool oldAllowSwitchOff = m_AllowSwitchOff;
m_AllowSwitchOff = true;
for (var i = 0; i < m_Toggles.Count; i++)
m_Toggles[i].isOn = false;
m_AllowSwitchOff = oldAllowSwitchOff;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment