Created
November 11, 2017 21:48
-
-
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.
This file contains 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
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; | |
} | |
} |
This file contains 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
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