Testing for Unity3D new uGUI system these day,
discover that the toggle button feature not good enough, so I design to write my own.
using UnityEngine; using UnityEngine.UI; [RequireComponent(typeof(Toggle))] public class ToggleEvent : MonoBehaviour { /// <summary>Delegate OnValueChanged event</summary> /// <param name="value">true/false</param> /// <example>this.OnValueChanged += YouMethod(bool value)</example> public delegate void ValueChanged(bool value); public ValueChanged OnValueChanged; protected Toggle toggle; protected virtual void OnEnable() { toggle = GetComponent<Toggle>(); toggle.onValueChanged.AddListener(WhenValueChanged); } protected virtual void OnDisable() { toggle.onValueChanged.RemoveListener(WhenValueChanged); } protected virtual void WhenValueChanged(bool value) { // Debug.Log(string.Format("{0} Toggle :{1}",GetType().Name.ToString(),value.ToString())); if (OnValueChanged != null) OnValueChanged(value); } }
the concept are simple using reflection to sync the target script component’s boolean value.
using UnityEngine; using UnityEngine.UI; using System; using System.Reflection; [RequireComponent(typeof(Toggle))] public class ToggleSync : ToggleEvent { /// <summary> /// For those too lazy to coding /// </summary> /// <remarks>Make sure all GameObject is allocated, component & property name are correct</remarks> [Tooltip("Target GameObject wanted to call")] public GameObject target; [Tooltip("Target Component Name on GameObject, throw error when null")] public string componentName; // public Component targetComponent; // hard to drag component [Tooltip("Target Property Name(Boolean) in Component, throw error when null")] public string propertyName; [Tooltip("Use ToggleEvent.OnValueChanged method")] public bool UseEventDelegate = false; protected override void OnEnable() { base.OnEnable(); toggle.isOn = GetValue(); } protected override void WhenValueChanged(bool value) { if (UseEventDelegate) base.WhenValueChanged(value); SetValue(value); } private bool GetValue() { if (target == null) return false; Component component = target.GetComponent(componentName); Type targetType = (component == null) ? null : component.GetType(); PropertyInfo propertyInfo = (targetType == null) ? null : targetType.GetProperty(propertyName); return (propertyInfo==null)?false:(bool)propertyInfo.GetValue(component, null); } private bool SetValue(bool value) { if (target == null) return false; string msg = string.Empty; Component component = target.GetComponent(componentName); Type targetType = (component == null) ? null : component.GetType(); PropertyInfo propertyInfo = (targetType == null) ? null : targetType.GetProperty(propertyName); if (ReferenceEquals(component, null)) { msg = string.Format("{0} cannot find component {1} on {2}", GetType().Name.ToString(), componentName, target.ToString()); } else if (ReferenceEquals(targetType, null)) { msg = string.Format("{0} component<{1}> is invaild {2}", GetType().Name.ToString(), componentName, target.ToString()); } else if (ReferenceEquals(null, propertyInfo)) { msg = string.Format("{0} cannot find property \"{1}\" on {2}", GetType().Name.ToString(), propertyName, target.ToString()); } else if (!propertyInfo.CanWrite) { msg = string.Format("{0} cannot assign property value \"{1}\" on {2}", GetType().Name.ToString(), propertyName, target.ToString()); } if (msg.Equals(String.Empty)) { propertyInfo.SetValue(component, value, null); return true; } else { Debug.LogError(msg); return false; } } }