zoukankan      html  css  js  c++  java
  • Unity插件扩展中组件常用的几个方法

    最近为美术编写一个Unity编辑器的扩展,主要为了减轻美术在修改预制对象时的机械化操作的繁琐和出错。具体实现的几个功能:

    1、删除指定组件;

    2、复制、粘贴指定的组件;

    3、重新关联新的属性;

    4、重新保存预制对象;

    一、删除指定类型的组件

    public static void RemoveComponentHandler(GameObject gameObject, Type componentType)
        {
            foreach (var component in gameObject.GetComponents<Component>())
            {
                if (component.GetType() == componentType)
                {
                    GameObject.DestroyImmediate(component);
                }
            }    
        }

    二、复制组件(这里实现的是一次仅复制一个某类型的组件)

    public static void CopyComponentHandler(Type componentType, GameObject fromGameObject, GameObject toGameObject)
        {
            RemoveComponentHandler(toGameObject, componentType);
    
            // 查找需要复制的 Component
            Component needCopyComponent = null;
            foreach (var component in fromGameObject.GetComponents<Component>())
            {
                if (component.GetType() == componentType)
                {
                    needCopyComponent = component;
                    break;
                }
            }
    
            // 进行粘贴操作
            // http://answers.unity3d.com/questions/907294/copy-all-components-from-a-gameobject-and-paste-to.html
            UnityEditorInternal.ComponentUtility.CopyComponent(needCopyComponent);
            UnityEditorInternal.ComponentUtility.PasteComponentAsNew(toGameObject);
        }

    三、关联新属性

    就是遍历指定的GameObject,然后找到它附加的组件,重新设置其值即可。

    四、替换预制对象

    GameObject activeGameObject = Selection.activeGameObject;
    if (activeGameObject != null)
    {
        // 获取当前的id
        if (new Regex(@"^d+h$").IsMatch(activeGameObject.name))
        {
            UnityEngine.Object parentObject = null;
            string strPrefabPath = "";
    
            if (PrefabUtility.GetPrefabType(activeGameObject) == PrefabType.PrefabInstance)
            {
                parentObject = EditorUtility.GetPrefabParent(activeGameObject);
                strPrefabPath = AssetDatabase.GetAssetPath(parentObject);
            }
    
            // 查找id
            string strId = new Regex(@"h$").Replace(activeGameObject.name, "");
    
            
            // 第六步 保存预制对象
            string strCurrSelectPrefabName = activeGameObject.name;
            if (strPrefabPath.EndsWith(".prefab"))
            {
                // string[] dependPaths = AssetDatabase.GetDependencies(strPrefabPath);
                GameObject go = GameObject.Instantiate(GameObject.Find(strCurrSelectPrefabName)) as GameObject;
                PrefabUtility.ReplacePrefab(go, parentObject, ReplacePrefabOptions.ConnectToPrefab);
    
                GameObject.DestroyImmediate(activeGameObject);
                go.name = strCurrSelectPrefabName;                    
    
                AssetDatabase.Refresh();
            }
    
            Debug.Log("预制对象 " + strCurrSelectPrefabName + " 修改完成。");
    
        }
        else
        {
            Debug.Log("当前选中的GameObject命名不符合要求,格式:id+h。	GameObject Name : " + activeGameObject.name);
        }           
    }

    最核心的几行代码:

    1、实例化一个新的GameObject;

    2、替换预制对象;

    3、销毁老的GameObject;

    4、刷新资源;

    对于美术的同事来讲,最复杂、麻烦的莫过于重新关联属性,特别是骨骼动画。因为之前没有统一的规范,所以关联哪一段动画实际上是需要一层一层找的,我看着他们找都觉得累,怎么办呢?我想到一个办法,就是通过name查找新的组件,然后重新赋值关联。通过Name查找某个GameObject下的子节点(前提条件是该Name唯一)

    public static GameObject FindChildGameObject(GameObject parent, string childName)
        {
            if (parent.name == childName)
            {
                return parent;
            }
    
            if (parent.transform.childCount < 1)
            {
                return null;
            }
    
            GameObject obj = null;
            for (int i = 0; i < parent.transform.childCount; i++)
            {
                GameObject go = parent.transform.GetChild(i).gameObject;
                obj = FindChildGameObject(go, childName);
                if (obj != null)
                {
                    break;
                }
            }
            return obj;
        }

    上面基本上实现了,组件几个常用的方法:

    1、添加组件(先复制后粘贴);

    2、删除组件;

    3、通过名字查找子组件;

    4、更新预制对象;

  • 相关阅读:
    memset使用技巧
    AcWing 843. n-皇后问题
    【Oracle】从12c开始支持的Oralce新分页方案
    Oracle历年版本发布情况
    【SpringBoot】又写了一份新瓶装旧酒的CRUD程序
    【SpringBoot/Actuator】给SpringBoot程序添加Actuator监控管理
    Top Cybersecurity Companies for 2021
    SNAT、DNAT、MASQUERADE的区别
    Flannel的两种模式解析(VXLAN、host-gw)
    kubelet 配置资源预留的姿势
  • 原文地址:https://www.cnblogs.com/meteoric_cry/p/7717903.html
Copyright © 2011-2022 走看看