Unity3D Bind插件之小试身手
____目前自学Unity3D也有一段时间了,前一段时间开始在一家刚创建没几个月的小公司上班。而公司用的是QFramework框架,我也是第一次接触框架,以前自学的时候没用过这么高大上的东西。刚接触还挺懵逼的,但是随着我不断的学习和了解这个框架,我发现意外的好用,比我以前没有框架时的开发效率提升了至少一倍。高大上啊~~
____这里不得不说凉大佬是真的牛逼https://blog.youkuaiyun.com/yukikit/article/details/99779247,我有尝试去理解里面的源码,发现自己功底还是差太多了,很多东西我都知道,但是怎么写就蒙圈了。最近也不断的活用这个框架和熟悉了解他,我发现对我开发效率提升最高的是Bind这个小功能,我非常喜欢这个功能,太方便了,再也不怕找不到对应的物体了。
所以我想尝试着去写一个类似的东西或者是小插件??首先我就想到了通过反射将其对应起来,再通过反射一一对应赋值,这也我目前能想到的东西了。然后写出了一个感觉、是的感觉差不多的插件(应该吧?),但是我去掉了一些东西,并且简化了一些,让我自己感觉挺上手的。
____接下来是功能介绍、使用说明:
功能介绍:主要是为了绑定目标,让我们不用在一个一个的去对应拖过去,要是不小心清掉了,再拖一遍想死的心都有了,项目越大越是难受,所以我借鉴了Qframwork的Bind功能,简化了大部分,只是单纯的绑定子物体而已。注意:要绑定的子物体的名字和父物体的脚本中的成员名字一定要一致,因为我就是靠带Bind的物体名字去判断对应是否属于对应成员。
使用说明:
1.先在父物体上添加Mark脚本,ComPoClass指定要绑定成员的脚本
2.接下来只要在对应成员上挂载Bind脚本。
好了,右键点击父物体选择ForBind就会自动绑定了。
最后献上代码 :
1.Bind类
using UnityEngine;
public class Bind : MonoBehaviour
{
}
2.Mark类
using UnityEngine;
public class Mark : MonoBehaviour
{
public Component CompoClass;
}
3.Editor_Bind类要放在Editor文件夹下,Editor文件夹可以有上级目录
namespace ForBind
{
using UnityEditor;
using UnityEngine;
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Text;
public class Editor_Bind : MonoBehaviour
{
/// <summary>
/// 对象
/// </summary>
private static Component targetCompo;
[MenuItem("GameObject/ForBind", priority = 29)]
public static void CreateUICode()
{
GameObject obj = Selection.activeGameObject;
if (!obj) return;
//获取标记的脚本
Mark mark = obj.GetComponent<Mark>();
if (!mark)
{
Debug.Log("请挂载Mark脚本");
return;
}
targetCompo = obj.GetComponent(mark.CompoClass.GetType().Name);
try
{
Type type = mark.CompoClass.GetType();
Dictionary<string, FieldInfo> dicNameField = FnmGetNameField(type);
Bind[] binds = obj.GetComponentsInChildren<Bind>(true);
foreach (Bind bind in binds)
{
if (dicNameField.TryGetValue(bind.name, out FieldInfo fInfo))
{
try
{
dicNameField[bind.name].SetValue(targetCompo, bind.GetComponent(dicNameField[bind.name].FieldType));
dicNameField.Remove(bind.name);
}
catch (Exception)
{
dicNameField[bind.name].SetValue(targetCompo, bind.gameObject);
dicNameField.Remove(bind.name);
}
}
}
if (dicNameField.Count > 0)
{
StringBuilder msg = new StringBuilder("==>成员 : ");
foreach (string name in dicNameField.Keys)
{
msg.Append(name + "、");
}
Debug.LogError(msg + " 无法绑定,请确认物体绑定了Bind脚本或名字与成员名是否一致。");
return;
}
}
catch (Exception e)
{
Debug.LogError("绑定对应物体出错了\n" + e.Message);
return;
}
Debug.Log("=====>获取物体" + obj.name + "上的脚本" + mark.CompoClass.name + "的成员成功了。");
}
/// <summary>
/// 查找脚本中所有需要绑定成员的名字、数据
/// </summary>
/// <param name="type">脚本类型</param>
/// <returns></returns>
private static Dictionary<string, FieldInfo> FnmGetNameField(Type type)
{
Dictionary<string, FieldInfo> dicNameField = new Dictionary<string, FieldInfo>();
foreach (FieldInfo field in type.GetFields())
{
if (!field.IsNotSerialized)
{
dicNameField[field.Name] = field;
}
}
return dicNameField;
}
}
}
PS:这是我第一次发帖,不足之处还请多多理解。喜欢自取就好,有能力就帮帮别人吧
PS:最近我又更新了一些小功能,比如当名字不相同时,智能配对等,有兴趣可以私聊我,一起探讨下。