编辑器之不实例化Prefab获取删除更新组件

使用 GetComponentsInChildren<>(true) 可以直接把Project视图里的子对象找出来!!!!

return;

代码是这样的

 
	[MenuItem("Assets/Delete")]
	static void delete () 
	{
		GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/GameObject.prefab");
 
		//删除MeshCollider
		MeshCollider [] meshColliders = prefab.GetComponentsInChildren<MeshCollider>(true);
		foreach(MeshCollider meshCollider in meshColliders){
 
			GameObject.DestroyImmediate(meshCollider,true);
		}
 
		//删除空的Animation组件
		Animation [] animations = prefab.GetComponentsInChildren<Animation>(true);
		foreach(Animation animation in animations){
			if(	animation.clip == null){
				GameObject.DestroyImmediate(animation,true);
			}
 
		}
 
		//删除missing的脚本组件
		MonoBehaviour [] monoBehaviours = prefab.GetComponentsInChildren<MonoBehaviour>(true);
		foreach(MonoBehaviour monoBehaviour in monoBehaviours){
 
 
			if(monoBehaviour == null){
				Debug.Log("有个missing的脚本");
				//GameObject.DestroyImmediate(monoBehaviour,true);
 
			}
		}
 
		//遍历Transform的名子, 并且给某个游戏对象添加一个脚本
		Transform [] transforms = prefab.GetComponentsInChildren<Transform>(true);
		foreach(Transform transfomr in transforms){
			if(transfomr.name == "GameObject (1)"){
				Debug.Log(transfomr.parent.name);
				transfomr.gameObject.AddComponent<BoxCollider>();
				return;
			}
 
		}
		//遍历Transform的名子, 删除某个GameObject节点
		foreach(Transform transfomr in transforms){
			if(transfomr.name == "GameObject (2)"){
				GameObject.DestroyImmediate(transfomr.gameObject,true);
				return;
			}
 
		}
                EditorUtility.SetDirty(prefab);
	}
 

今天有朋友说不能删除missing的脚本, 我试了一下确实不行。 随后查了一下, 可以用这个方法来删除,

How do I Remove null components ( i.e. "Missing(Mono Script)" ) via editor script? - Unity Answers

 
 [MenuItem("Edit/Cleanup Missing Scripts")]
 static void CleanupMissingScripts ()
 {
     for(int i = 0; i < Selection.gameObjects.Length; i++)
     {
         var gameObject = Selection.gameObjects[i];
         
         // We must use the GetComponents array to actually detect missing components
         var components = gameObject.GetComponents<Component>();
         
         // Create a serialized object so that we can edit the component list
         var serializedObject = new SerializedObject(gameObject);
         // Find the component list property
         var prop = serializedObject.FindProperty("m_Component");
         
         // Track how many components we've removed
         int r = 0;
         
         // Iterate over all components
         for(int j = 0; j < components.Length; j++)
         {
             // Check if the ref is null
             if(components[j] == null)
             {
                 // If so, remove from the serialized component array
                 prop.DeleteArrayElementAtIndex(j-r);
                 // Increment removed count
                 r++;
             }
         }
         
         // Apply our changes to the game object
         serializedObject.ApplyModifiedProperties();
         //这一行一定要加!!!
         EditorUtility.SetDirty(gameObject);
     }
 }
 

昨天晚上睡觉的时候脑洞打开。因为做项目的时候我们可能要在编辑器上做很多检查工具一类的东西。 这里我说几个典型的例子,比如空的Animation组件、丢失的脚本、没用的meshCollider组件。这些东西我们是不需要的,但是美术可能不会不小心加到prefab里。

以前的做法是 先要把Prefab 实例化 Instance以后  然后  GetComponentsInChildren  把所有的组件都取出来。 在进行遍历删除。 然后还要DestroyImmediate 它。 。那么如果prefab数量比较多的话,那么检查一次时间是很漫长的。

如果你只是想找组件 空脚本 一类的。用如下代码就可以不实例化并且找出来。

如果你想不实例化并且修改数据的话,那么可以考虑用下面的方法。

1.先把prefab 序列化的方式改成text 用File就可以把prefab的文本信息读出来。

 
File.ReadAllText("xxx/xxx.prefab")
 

2.prefab文本序列化的结构,如下图所示,看到!u!111了吗  111 是一组id .它是有意义的(它表示Animation),标着着这个组件是个啥东西。 具体是什么含义大家可以去这里查 Unity - Manual: YAML Class ID Reference

 

3.自定义脚本

如果我想查一下看看prefab有没有绑定我自己写的脚本怎么办呢?如下图所 ,guid这一栏 就写的是你的脚本的guid了。

 然后在脚本对应的mate文件里就记录这这个脚本的guid ,如果这两个id匹配,那么就说明这个prefab里挂着这个脚本了。

 

最后就交给正则表达式做第一步的匹配吧。 这样的话第一步就可以筛选掉一大批prefab了。 如果还需要进行验证在进一步的Instance来检查吧。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值