Unity UI组件自动绑定工具C#

Unity UI组件自动绑定工具C#

Unity针对UI组件,不用再拖动UI组件到脚本上来绑定组件,钮点击事件利用反射绑定方法,无需提前硬编码,需要的UI组件通过组件名字自动绑定对应的组件
比如我规定组件名字需要以mText,mBtn,mImg开头

以下是核心代码UIbase,遍历父节点下的所有物体,通过名字自动绑定对应组件

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using UnityEngine.UI;

public class UIBase : MonoBehaviour
{
    Dictionary<string, UnityEngine.Object> itemsDic = new Dictionary<string, UnityEngine.Object>();

    private bool isInit = false;

    /// 
    /// 初始化UI
    /// 
    public virtual void InitUI()
    {
        if (isInit == false)
        {
            BindUI();
            isInit = true;
        }
    }

    /// 
    /// 绑定UI组件
    /// 
    void BindUI()
    {
        string _name = "";
        foreach (Transform obj in this.GetComponentsInChildren<Transform>(true))
        {
            _name = obj.gameObject.name;
            if (_name.StartsWith("mBtn") || _name.StartsWith(":"))
            {
                if (obj.GetComponent<Button>())
                {
                    BindButton(obj.GetComponent<Button>());
                    if (_name.StartsWith("mBtn"))
                    {
                        _name = _name.Split(':')[0];
                        itemsDic.Add(_name, obj.GetComponent<Button>());
                    }
                }
            }
            else if (_name.StartsWith("mGO"))
            {
                itemsDic.Add(_name, obj.gameObject);
            }
            else if (_name.StartsWith("mText"))
            {
                if (obj.GetComponent<Text>())
                {
                    itemsDic.Add(_name, obj.GetComponent<Text>());
                }
            }
            else if (_name.StartsWith("mImg"))
            {
                if (obj.GetComponent<Image>())
                {
                    itemsDic.Add(_name, obj.GetComponent<Image>());
                }
            }
            else if (_name.StartsWith("mRImg"))
            {
                if (obj.GetComponent<RawImage>())
                {
                    itemsDic.Add(_name, obj.GetComponent<RawImage>());
                }
            }
            else if (_name.StartsWith("mSlider"))
            {
                if (obj.GetComponent<Slider>())
                {
                    itemsDic.Add(_name, obj.GetComponent<Slider>());
                }
            }
            else if (_name.StartsWith("mToggle"))
            {
                if (obj.GetComponent<Toggle>())
                {
                    itemsDic.Add(_name, obj.GetComponent<Toggle>());
                }
            }
            else if (_name.StartsWith("mInput"))
            {
                if (obj.GetComponent<InputField>())
                {
                    itemsDic.Add(_name, obj.GetComponent<InputField>());
                }
            }
        }
    }

    /// 
    /// 获取组件
    /// 
    /// 
    /// 
    /// 
    public T _Get<T>(string name) where T : UnityEngine.Object
    {
        if (itemsDic.ContainsKey(name))
        {
            return (T)itemsDic[name];
        }
        else
        {
            if (isInit == false)
            {
                Debug.LogError(this.GetType().Name + "未初始化,请检查是否先调用了基类的InitUI方法");
            }
            else if (itemsDic.Count == 0)
            {
                Debug.LogError("字典里没东西");
            }
            else
            {
                Debug.LogError("在" + this.GetType().Name + "面板下找不到组件:" + name);
            }
            return null;
        }
    }

    /// 
    /// 绑定按钮的点击事件
    /// 
    /// 
    void BindButton(Button button)
    {
        string[] comName = button.name.Split(':');
        string methodName = comName[1];

        Type t = Type.GetType(this.GetType().Name);

        System.Reflection.MethodInfo method = t.GetMethod(methodName);
        if (method == null)
        {
            System.Reflection.BindingFlags flags = System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance;
            method = t.GetMethod(methodName, flags);
        }
        //绑定的方法要public或者private,需要其他的自行扩展
        if (method != null)
        {
            button.onClick.AddListener(() =>
            {
                method.Invoke(this, null);
            });
        }
    }
    //扩展:绑定其他事件
}

下面是例子,其他的面板只要继承自UIbase即可

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class TestPanel : UIBase
{
    readonly string mGOContent = "mGOContent";
    readonly string mTextInfo = "mTextInfo";
    readonly string mImgShow = "mImgShow";
    readonly string mBtnShow = "mBtnShow";
    readonly string mBtnHide = "mBtnHide";

    private void Awake()
    {
        InitUI();
    }

    public override void InitUI()
    {
        base.InitUI();
        _Get<Image>(mImgShow).color = Color.black;
        _Get<Text>(mTextInfo).text = "Black";
    }

    void ShowUI()
    {
        _Get<GameObject>(mGOContent).SetActive(true);
        _Get<Button>(mBtnShow).interactable = false;
        _Get<Button>(mBtnHide).interactable = true;
    }

    void HideUI()
    {
        _Get<GameObject>(mGOContent).SetActive(false);
        _Get<Button>(mBtnShow).interactable = true;
        _Get<Button>(mBtnHide).interactable = false;
    }

    void OnClickChangeToRed()
    {
        _Get<Image>(mImgShow).color = Color.red;
        _Get<Text>(mTextInfo).text = "Red";
    }

    void OnClickChangeToYellow()
    {
        _Get<Image>(mImgShow).color = Color.yellow;
        _Get<Text>(mTextInfo).text = "Yellow";
    }
}

我选择代码中使用下划线Get来获取组件,加下划线是为了编码是更快速找到,因为通过名字来绑定组件的,写成_Get(“mImgShow”)的话,以后组件要更换名字会很麻烦,所以一开始会定义在代码中,如readonly string mTextInfo = “mTextInfo”;,因为不需要修改,所以写成只读的。

我这里只是抛砖引玉,你可以结合这个进行改进,扩展,有了这个脚本,编写UI更轻松了,所以。。求求你,求求你别再把脚本拖动到按钮的点击事件里,然后选择调用哪个public方法了,别再public组件然后,把组件拖到脚本里赋值了

以下是一个很简单的使用范例,我使用的是Unity2018.4.3
Unity UI组件自动绑定工具范例
百度网盘
链接:https://pan.baidu.com/s/15SuqNrTl3SYHl6Wyxrd9jg
提取码:CJZS

里面也有针对父面板下的子面板想单独赋值的解决方法,就是再写一个UIbase,使用另一套命名规则就行了

=================================================================

你可能感兴趣的:(Unity,c#,unity3d,ugui,ui)