最近为美术编写一个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。\tGameObject 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、更新预制对象;

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. exshop第6天

    发现grails mongodb插件中的一个BUG并进行了提交,grails项目管理人员还进行了回复,主要是配置failOnError 后不起作用了,不过项目负责人还是确认了这个问题,估计会比较快的解 ...

  2. day100-序列化组件

    3 序列化组件 class BookSerializer(serializers.Serializer): title = serializers.CharField( max_length=32) ...

  3. nignx部署Vue单页面刷新路由404问题解决

    官网说明: https://router.vuejs.org/zh/guide/essentials/history-mode.html#%E8%AD%A6%E5%91%8A 在linux下搭建ngi ...

  4. Javascript转义字符串中的特殊字符处理

    Web应用系统中,客户端发送请求到服务器,请求中的字符串参数,在被序列化成json过程中有些特殊字符会被空格代, 导致传递到服务器端再解析的时候,原本的输入参数就会被改变. 目前遇到的特殊字符有加号( ...

  5. 查看windows电脑CPU核心数,线程数

    在Windows中,在cmd命令中输入“wmic”,然后在出现的新窗口中输入“cpu get *”即可查看物理CPU数.CPU核心数.线程数.其中,  Name:表示物理CPU数  NumberOfC ...

  6. HDU3488 Tour KM

    原文链接http://www.cnblogs.com/zhouzhendong/p/8284304.html 题目传送门 - HDU3488 题意概括 给一个n的点m条边的有向图. 然后让你把这个图分 ...

  7. BZOJ2212 [Poi2011]Tree Rotations 线段树合并 逆序对

    原文链接http://www.cnblogs.com/zhouzhendong/p/8079786.html 题目传送门 - BZOJ2212 题意概括 给一棵n(1≤n≤200000个叶子的二叉树, ...

  8. LBS基站定位

    LBS基站定位(Location Based Service,简称LBS)一般应用于手机用户,它是基于位置的服务,通过电信.移动运营商的无线电通讯网络(如GSM网.CDMA网)或外部定位方式(如GPS ...

  9. Sumdiv POJ - 1845 (逆元/分治)

    Consider two natural numbers A and B. Let S be the sum of all natural divisors of A^B. Determine S m ...

  10. Linux下发送邮件

    Linux下发送邮件 1.配置 vim /etc/mail.rc 文件尾增加以下内容 set from=ymwugui@linuxidc.com smtp=smtp.sina.com.cn set s ...