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

1、删除指定组件;

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

3、重新关联新的属性;

4、重新保存预制对象;

一、删除指定类型的组件

  1. public static void RemoveComponentHandler(GameObject gameObject, Type componentType)
  2. {
  3. foreach (var component in gameObject.GetComponents<Component>())
  4. {
  5. if (component.GetType() == componentType)
  6. {
  7. GameObject.DestroyImmediate(component);
  8. }
  9. }
  10. }

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

  1. public static void CopyComponentHandler(Type componentType, GameObject fromGameObject, GameObject toGameObject)
  2. {
  3. RemoveComponentHandler(toGameObject, componentType);
  4.  
  5. // 查找需要复制的 Component
  6. Component needCopyComponent = null;
  7. foreach (var component in fromGameObject.GetComponents<Component>())
  8. {
  9. if (component.GetType() == componentType)
  10. {
  11. needCopyComponent = component;
  12. break;
  13. }
  14. }
  15.  
  16. // 进行粘贴操作
  17. // http://answers.unity3d.com/questions/907294/copy-all-components-from-a-gameobject-and-paste-to.html
  18. UnityEditorInternal.ComponentUtility.CopyComponent(needCopyComponent);
  19. UnityEditorInternal.ComponentUtility.PasteComponentAsNew(toGameObject);
  20. }

三、关联新属性

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

四、替换预制对象

  1. GameObject activeGameObject = Selection.activeGameObject;
  2. if (activeGameObject != null)
  3. {
  4. // 获取当前的id
  5. if (new Regex(@"^\d+h$").IsMatch(activeGameObject.name))
  6. {
  7. UnityEngine.Object parentObject = null;
  8. string strPrefabPath = "";
  9.  
  10. if (PrefabUtility.GetPrefabType(activeGameObject) == PrefabType.PrefabInstance)
  11. {
  12. parentObject = EditorUtility.GetPrefabParent(activeGameObject);
  13. strPrefabPath = AssetDatabase.GetAssetPath(parentObject);
  14. }
  15.  
  16. // 查找id
  17. string strId = new Regex(@"h$").Replace(activeGameObject.name, "");
  18.  
  19. // 第六步 保存预制对象
  20. string strCurrSelectPrefabName = activeGameObject.name;
  21. if (strPrefabPath.EndsWith(".prefab"))
  22. {
  23. // string[] dependPaths = AssetDatabase.GetDependencies(strPrefabPath);
  24. GameObject go = GameObject.Instantiate(GameObject.Find(strCurrSelectPrefabName)) as GameObject;
  25. PrefabUtility.ReplacePrefab(go, parentObject, ReplacePrefabOptions.ConnectToPrefab);
  26.  
  27. GameObject.DestroyImmediate(activeGameObject);
  28. go.name = strCurrSelectPrefabName;
  29.  
  30. AssetDatabase.Refresh();
  31. }
  32.  
  33. Debug.Log("预制对象 " + strCurrSelectPrefabName + " 修改完成。");
  34.  
  35. }
  36. else
  37. {
  38. Debug.Log("当前选中的GameObject命名不符合要求,格式:id+h。\tGameObject Name : " + activeGameObject.name);
  39. }
  40. }

最核心的几行代码:

1、实例化一个新的GameObject;

2、替换预制对象;

3、销毁老的GameObject;

4、刷新资源;

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

  1. public static GameObject FindChildGameObject(GameObject parent, string childName)
  2. {
  3. if (parent.name == childName)
  4. {
  5. return parent;
  6. }
  7.  
  8. if (parent.transform.childCount < 1)
  9. {
  10. return null;
  11. }
  12.  
  13. GameObject obj = null;
  14. for (int i = 0; i < parent.transform.childCount; i++)
  15. {
  16. GameObject go = parent.transform.GetChild(i).gameObject;
  17. obj = FindChildGameObject(go, childName);
  18. if (obj != null)
  19. {
  20. break;
  21. }
  22. }
  23. return obj;
  24. }

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

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

2、删除组件;

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

4、更新预制对象;

Unity插件扩展中组件常用的几个方法的更多相关文章

  1. [Unity]Unity3D编辑器插件扩展和组件扩展

    1. 插件扩展 1.1. 命名空间 using UnityEditor; using UnityEngine; //非必需,常用到 1.2. 使用语法 [MenuItem("Assets/M ...

  2. Vue中组件通信的几种方法(Vue3的7种和Vue2的12种组件通信)

    Vue3组件通信方式: props $emit expose / ref $attrs v-model provide / inject Vuex 使用方法: props 用 props 传数据给子组 ...

  3. 通过写一个Demo展示C#中多种常用的集合排序方法

    不多说,程序很简单,就是将集合中的数据进行排序,但使用到的知识点还是比较多的,大牛勿喷,谨献给初学者!直接上程序吧! namespace Demo { /// <summary> /// ...

  4. JAVA中正则表达式常用的四个方法

    JAVA中正则表达式处理字符串的四个常用方法:匹配.分割.替换.截取.其跟字符串的常用函数相似,但是使用正则表达式会更简单.更加简洁.下面是具体的例子: public class TestRegex ...

  5. laravel中及其常用的一些函数方法(自己看)和技巧(不断添加中)

    手册:https://laravelacademy.org/ 1.中间件的定义Middleware 2.路由的定义和写法 3.控制器Controller之Request 4.控制器Controller ...

  6. db2 查看进程 db2中的常用命令及使用方法

    一 高(重要度) 1 启动一个db 2实例使用: net start instanceName 2 停止一个db 2实例使用: net stop instanceName 3 启动配置助手: db2= ...

  7. Hutool中那些常用的工具类和方法

    Hutool中那些常用的工具类和方法 Hutool是一个Java工具包,它帮助我们简化每一行代码,避免重复造轮子.如果你有需要用到某些工具方法的时候,不妨在Hutool里面找找,可能就有.本文将对Hu ...

  8. nginx 常用的 URL 重写方法

    转自:http://www.jbxue.com/article/4727.html Nginx中一些常用的URL 重写方法介绍,有需要的朋友可以参考下.url重写应该不陌生,不管是SEO URL 伪静 ...

  9. JavaScript中的Array.prototype.slice.call()方法学习

    JavaScript中的Array.prototype.slice.call(arguments)能将有length属性的对象转换为数组(特别注意: 这个对象一定要有length属性). 但有一个例外 ...

随机推荐

  1. Android测试环境搭建

    Android测试环境搭建 一.操作系统 使用Win7_64位操作系统.(可以用其他的系统,下面都是针对Win7 64位进行操作) 二.安装JDK 运行jdk-6u45-windows-x64.exe ...

  2. 20165235 祁瑛 2018-4 《Java程序设计》第六周学习总结

    20165235 祁瑛 2018-4 <Java程序设计>第六周学习总结 教材学习内容总结 常用实用类 (一)1.String类是final类型的,String类型常量也是对象.2.可以使 ...

  3. 蓝桥杯 跳蚱蜢 (bfs)

    转载自:https://blog.csdn.net/wayway0554/article/details/79715658 本题的解题关键就在于将蚱蜢在跳转换为盘子在跳. 当使用string当做每一个 ...

  4. CentOS6.2(64bit)下mysql5.6.16主从同步配置

    1. 主配置,进入mysql.cnf在[mysqld]下面添加以下配置 [root@localhost ~]# vi /etc/mysql.cnf server-id=1 binlog-format= ...

  5. fastAdmin进阶

    基本知识流程一栏链接 bootstrapTable fastadmin系统配置(符内置规则): fastadmin默认的controller已实现的方法 一张图解析fastadmin的表格: fast ...

  6. 在Visual Sutdio 2017中使用boost库

    在Visual Sutdio 2017中使用boost库     转载 https://blog.csdn.net/u011054333/article/details/78648294 对C++有一 ...

  7. HDU 2586 How far away ?(经典)(RMQ + 在线ST+ Tarjan离线) 【LCA】

    <题目链接> 题目大意:给你一棵带有边权的树,然后进行q次查询,每次查询输出指定两个节点之间的距离. 解题分析:本题有多重解决方法,首先,可用最短路轻易求解.若只用LCA解决本题,也有三种 ...

  8. AngularJS的Scope和Digest

    Angular是一个成熟和强大的JavaScript框架.它也是一个比较庞大的框架,在熟练掌握之前,需要领会它提出的很多新概念.很多Web开发人员涌向Angular,有不少人面临同样的障碍.Diges ...

  9. Oracle date 详解

    oracle 数据类型详解---日期型 oracle数据类型看起来非常简单,但用起来会发现有许多知识点,本文是我对ORACLE日期数据类型的一些整理,都是开发入门资料,与大家分享:注:由于INTERV ...

  10. C#相关FTP操作

    C# 相关 FTP(File Transfer Protocol) 操作 1.获取文件目录 UsePassive:需要设置为false. 使用被动模式,因为客户端防火墙的存在,所以为了确保数据可以正常 ...