最近,鱼鱼经过大学的学习生涯,也是成功进入了游戏行业(虽然只是一个苦逼的小程序员),总算是切身体会到了“传说”中的UI仔是怎么一回事。
在一番挣扎后,鱼鱼想到了一个办法减少繁琐重复的UI组件赋值问题。
废话不多说,直接展示
这是鱼鱼在获取UI组件和给按钮绑定事件的时候常用的方法,一旦需要的UI组件多了后,会非常折磨人,如果对UI的名称,父子关系进行了更改,代码也要更改,一个不注意就会报错
为了摸鱼(划掉)提高工作效率,鱼鱼于是想到了利用反射获取字段,自动获取组件的方法
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Reflection;
using System;
public class BasePanelTest:MonoBehaviour
{
protected virtual void Awake()
{
//Auto_Init();
}
/// <summary>
/// ui自动初始化
/// </summary>
protected virtual void Auto_Init()
{
Type type = this.GetType();
BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance;
// 1.获取类中的属性,字段//属性不用获取
//2.找到引用类型字段
//3.在子物体中搜索同名的物体
//4.获取子物体上的组件
Dictionary<string, FieldInfo> wait = new Dictionary<string, FieldInfo>();
FieldInfo[] fieldInfos = type.GetFields(flags);
foreach(FieldInfo fi in fieldInfos)
{
//Debug.Log("类型:" + fi.FieldType + "名字:" + fi.Name);
if (!fi.FieldType.IsValueType)
{
wait.Add(fi.Name, fi);
}
}
TraversalTransfrom(wait, transform);
}
/// <summary>
/// 递归遍历所有子物体
/// </summary>
protected void TraversalTransfrom(Dictionary<string,FieldInfo> dic, Transform node)
{
if (dic.ContainsKey(node.name))
{
//Type t= dic[node.name];
dic[node.name].SetValue(this, node.GetComponent(dic[node.name].FieldType.Name));
//Debug.Log("添加成功" + node.GetComponent(dic[node.name].FieldType.Name)+":"+node.name);
}
for (int i=0;i<node.childCount;i++)
{
TraversalTransfrom(dic, node.GetChild(i));
}
}
}
代码很简单,利用反射获取引用类型的字段,然后递归遍历挂载脚本的物体和它的子物体,找物体寻名字和字段名字相同的物体,获取该物体身上的组件,最后将组件的引用设置给字段。
这样,就完成了ui脚本类所需组件的自动赋值,不过看各位大佬关于反射的文章,似乎比较消耗性能,但鱼鱼并没有深入的去研究。
如果运行时卡顿比较明显,可以将赋值过程放到携程里去。
另外,鱼鱼目前在使用的UI框架,每个UIPanel都要创建一遍脚本,然后继承,重写,引用命名空间。。。这样重复的工作占用了鱼鱼的单线程大脑,让鱼鱼没法思考了,后续会用编辑器实现一个UIPanel脚本自动化创建的功能,感兴趣的话可以点个关注。
另,若有不足或有更好的办法,还请指出,感谢!