Unity3D uGUI Toggle button

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;
        }
    }
}

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

*

這個網站採用 Akismet 服務減少垃圾留言。進一步瞭解 Akismet 如何處理網站訪客的留言資料