您的位置:首页 > 移动开发 > Unity3D

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

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);
}
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  unity ui 界面
相关文章推荐