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,使用另一套命名规则就行了
=================================================================