欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Unity 3d UGUI 快速对组件复制

程序员文章站 2022-03-20 11:17:44
...

      在项目开发过程中,UI要求脚本变量的命名与UI场景中的Gamobejct的名字保持一致,以达到开发的时候,容易迅速确认错误,(比如在寻在一个Button点击事件时,变量名与场景中的名字不一致,会导致我知道这个Button被点击,Text的被赋值的,但是在场景中如果名称不一样,找起来相当麻烦,确认问题会很浪费时间)。

      在命名的基础上,我做了一个功能,主要是通过反射,获取对应UI预设的与继承Mon脚本的中名称与类型相同的UI脚本中的变量,进行快速赋值,节省时间,不用在完成对应UI脚本编写以后,一个一个拖上去。自动完成,前提是,命名必须符合上面说道的规则。

using System;
using System.Reflection;
using UnityEngine;
using System.Collections.Generic;

public class BindAbleMonoBehaviour : MonoBehaviour {
    /// <summary>[ContextMenu("TestSetVar")]
    /// 该特性 可以 在Unity->Inspector面板右键弹出菜单添加一个按钮。
    /// 点击触发下面的方法 快速对已经定义的变量进行赋值
    /// </summary>
    [ContextMenu("Bind Property")]
    void BindProperty()
    {
        Bind(this);//使用工具类对当前选中对象进行 变量赋值
    }

    public static void Bind(MonoBehaviour targetMonoBhv)
    {
        //反射遍历一个类的属性,参照文章:https://www.cnblogs.com/cuihongyu3503319/archive/2011/11/04/2235634.html
        CacheGameObjet cacehGmObj = new CacheGameObjet(targetMonoBhv);
        Type t = targetMonoBhv.GetType();
        //注意, 目标类的变量必须要设置了get 和set方法的属性,反射才能获得该属性
        FieldInfo[] propertyList = t.GetFields();
        List<string> strX = new List<string>();
        foreach (FieldInfo item in propertyList)
        {
            //作用于排除继承于MonoBehaviour,MonoBehaviour 的自带 变量
            if (item == null)
            {
                Debug.Log("挂载的脚本未赋值");
            }

            //对下面这个鞋类型不去检测与获取
            if (item.FieldType == typeof(float) ||
                item.FieldType == typeof(int) ||
                item.FieldType == typeof(double) ||
                item.FieldType == typeof(double) ||
                item.FieldType == typeof(Vector2) ||
                item.FieldType == typeof(Vector3) ||
                item.FieldType == typeof(Vector4) ||
                item.FieldType == typeof(Sprite) ||
                item.FieldType == typeof(Enum) ||
                item.FieldType == typeof(Quaternion) ||
                item.FieldType == typeof(Rect) ||
                item.FieldType == typeof(AnimationCurve)
                )
            {
                continue;
            }

            Transform gmObj = cacehGmObj.GetObj(item.Name);//从子对象里面找名字相同的对象。
            if (gmObj == null)
            {
                Debug.Log("<color=red>请注意,这个变量没有赋值(不存在此名字的Object)!!这个变量:[" + item.Name + "]</color>");
                continue;
            }

            if (gmObj != null)
            {
                Type monobhv = item.FieldType;//.GetType();
                if (item.FieldType == gmObj.gameObject.GetType())
                {
                    if (item.GetValue(targetMonoBhv) == null)
                    {
                        strX.Add("Type:" + gmObj.gameObject.GetType() + " Name:<color=green>" + item.Name + "</color>");
                    }
                    item.SetValue(targetMonoBhv, gmObj.gameObject);//给变量赋值
                    continue;
                }
                object tagertObject = gmObj.GetComponent(monobhv);
                if (tagertObject != null)
                {
                    if (item.GetValue(targetMonoBhv) == null)
                    {
                        strX.Add("Type:" + monobhv + "  Name:<color=green>" + item.Name + "</color>");
                    }
                    item.SetValue(targetMonoBhv, tagertObject);//给变量赋值
                }
                else
                {
                    Debug.Log("<color=red>请注意,这个变量没有赋值!!这个变量:[" + item.Name + "]1.有对应的GameObject,但是没有想要的组件:" + monobhv.ToString() + "</color>");
                }
            }
        }
        Debug.Log("赋值列表数:" + strX.Count + "\n");
        for (int i = 0; i < strX.Count; i++)
        {
            Debug.Log(strX[i] + "\n");
        }


    }
    }

    public struct CacheGameObjet
    {
        public Transform[] allChilds;
        public CacheGameObjet(MonoBehaviour parent)
        {
            allChilds = parent.GetComponentsInChildren<Transform>();
        }

        /// <summary>从子对象里查找 指定Name  的 对象并返回
        /// </summary>
        /// <param name="nameX"></param>
        /// <returns></returns>
        public Transform GetObj(string name)
        {
            for (int i = 0; i < allChilds.Length; i++)
            {
                if (allChilds[i].name.ToUpper() == name.ToUpper())
                {
                    return allChilds[i];
                }
            }
            return null;
        }
    }

 

如果想使用此方法,把原来继承自MonoBehaviour,改为BindAbleMonoBehaviour

Unity 3d UGUI 快速对组件复制

使用右键

Unity 3d UGUI 快速对组件复制

会自动对场景此UI脚本与添加上对应的Gameobject

Unity 3d UGUI 快速对组件复制

相关标签: Unity 3d