Unity通过Attribute代替getComponent获取组件
2017-08-10 22:16
309 查看
每次用Unity做了一个界面,写代码时都要为了获取UI的组件或者子物体而写一堆的
Transform.FindChild 和 getComponent 这么做虽然没什么错,但是写出来的代码
太难看了,冗余代码也多,实在受不了了,所以写了一个工具类,通过C#的Attribute
特性来获取组件和子物体
先看效果
这里有一个物体,包含a,b,c 三个子物体
c物体上挂有SpriteRenderer组建
想在我们给GameObject添加一个测试脚本Test
正常情况下我们会这么做:
现在我们不这么写了:
下面是运行结果:
可以看到c和SpriteRenderer都拿到了
如果我们想自动为c附加个Button组件
可以直接这样:
运行后我们就可以看到Button了
很简单省事吧。
下面是代码
PathAttr.cs
PathMono.cs
Transform.FindChild 和 getComponent 这么做虽然没什么错,但是写出来的代码
太难看了,冗余代码也多,实在受不了了,所以写了一个工具类,通过C#的Attribute
特性来获取组件和子物体
先看效果
这里有一个物体,包含a,b,c 三个子物体
c物体上挂有SpriteRenderer组建
想在我们给GameObject添加一个测试脚本Test
正常情况下我们会这么做:
现在我们不这么写了:
下面是运行结果:
可以看到c和SpriteRenderer都拿到了
如果我们想自动为c附加个Button组件
可以直接这样:
运行后我们就可以看到Button了
很简单省事吧。
下面是代码
PathAttr.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; [AttributeUsage(AttributeTargets.Field)] public class PathAttr : Attribute { public string path = ""; public int type = 1; public PathAttr(string path){ this.path = path; } public PathAttr(string path, int type){ this.path = path; this.type = type; } }
PathMono.cs
using System; using System.Collections; using System.Collections.Generic; using System.Reflection; using UnityEngine; using UnityEngine.UI; public class PathMono : MonoBehaviour { private void InitAdd(string path, FieldInfo fi) { Type type = fi.FieldType; string[] pathes = path.Split('/'); Transform nowPos = transform; if (!string.IsNullOrEmpty(path)) { for (int i = 0; i < pathes.Length; i++) { string nodeName = pathes[i]; Transform trans = nowPos.FindChild(nodeName); if (trans == null) { GameObject newGO = new GameObject(nodeName); newGO.transform.SetParent(nowPos); nowPos = newGO.transform; continue; } else { nowPos = trans; continue; } } } if (type.IsSubclassOf(typeof(Component))) { Component c = nowPos.GetComponent(type); if (c == null) c = nowPos.gameObject.AddComponent(type); fi.SetValue(this, c); } else if (type == typeof(GameObject)) { fi.SetValue(this, nowPos.gameObject); } } public void Init() { BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public; FieldInfo[] fi = this.GetType().GetFields(flag); for (int i = 0; i < fi.Length; i++) { FieldInfo f = fi[i]; PathAttr mn = Attribute.GetCustomAttribute(f, typeof(PathAttr)) as PathAttr; if (mn == null) continue; if (mn.type == 2) { InitAdd(mn.path, f); continue; } string path = mn.path; Transform trs = null; if (string.IsNullOrEmpty(path)) { trs = transform; } else { trs = transform.FindChild(path); } if (trs == null) { if (mn.type == 1) { continue; } else if (mn.type == 3) { InitAdd(path, f); } } else { if (f.FieldType.IsSubclassOf(typeof(Component))) { Component c = trs.GetComponent(f.FieldType); if(c == null && mn.type == 3){ c = trs.gameObject.AddComponent(f.FieldType); } f.SetValue(this, c); } else if (f.FieldType == typeof(GameObject)) { f.SetValue(this, trs.gameObject); } else if (f.FieldType == typeof(Transform)) { f.SetValue(this, trs); } } } } }
相关文章推荐
- 为什么通过GetComponent获取的组件,有时修改会无效?
- unity5.x Translate平移移动 以及GetComponent获取组件
- Unity 通过代码获取从面板传入的mono脚本,并添加为GameObject的脚本组件
- Android 通过反射获取系统组件的私有变量,并做更改
- unity中如何获取所有子物体的组件
- Unity获取物体组件调用
- 面向组件编程之Unity 1.怎样获取脚本所在物体的各种组件,例如:transform/BoxCollider
- react父组件通过ref获取不到子组件方法的解决方案
- C#给枚举增加一个Attribute,并通过反射获取Attribute的值。(借鉴)
- 学习笔记:Unity战斗卡牌游戏(一)-----NGUI基础组件使用及代码修改获取
- unity 不通过gameobject寻找物体 查找指定父物体的指定名称的子物体,指定组件,指定类型的组件
- 通过checkbox的属性理解jquery获取attribute与property
- 2017.08.04 通过openGL纹理在Unity中获取摄像机图像
- Flex编程注意之直接获取某个组件的对象(this[]用法)通过id获取控件
- unity通过天气接口获取json数据
- unity新版粒子特效的组件获取
- 【Unity&精灵】如何通过已知道的坐标获取物体&动态生成墙壁
- Flex编程注意之直接获取某个组件的对象(this[]用法)通过id获取控件
- MVC扩展Filter,通过继承HandleErrorAttribute,使用log4net或ELMAH组件记录服务端500错误、HttpException、Ajax异常等
- MVC 通过继承HandleErrorAttribute,使用log4net或ELMAH组件记录异常等