Unity Editor自制工具(1)--“Editor目录栏按钮+全局搜索方法+自制Editor窗口”实现搜索与删除场景中任意名称游戏物体

1,制作Editor上方目录按钮

在C#静态方法上方加上[MenuItem(“目录”)],可在Editor中上方目录栏生成一个按钮。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class LiusCustomEditor : MonoBehaviour {

	[MenuItem("LiusTool/Delete_H2_1")]
	static void Delete_H2_1(){
	}
}

这里写图片描述
(图1:利用MenuItem特性实现上Editor上方目录按钮)

2,非运行状态下对项目中所有对象进行全局搜索

假如在场景中有很多gameObject,而它们又都有很复杂的父子物体结构(如下图),如果在Editor中想对它们进行批量修改是很麻烦的,没法全部圈选。可选择用脚本写代码进行操作,这时可以调用Resources.FindObjectsofTypeAll<>方法。
这里写图片描述
(图2:场景中有很多带有父子结构的游戏物体)

给Delete_H2_1方法填肉,可实现删除场景中所有名字为“H2(1)”的gameObject:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class LiusCustomEditor : MonoBehaviour {

	[MenuItem("LiusTool/Delete_H2_1")]
	static void Delete_H2_1(){
		Transform[] CUs=Resources.FindObjectsOfTypeAll<Transform> ();
		foreach (Transform temp in CUs) {
			if (temp.name == "H2 (1)") {
				DestroyImmediate (temp.gameObject);
			}
		}
	}
}

Resources.FindObjetsOfTypeAll<Transform>() 将会搜索项目中已经加载的所有类型为Transform的对象,包括场景中已关闭的游戏物体以及Assets文件夹中的各种资源以及内部隐藏对象,然后通过检查它们的名字进行下一步操作。
根据官方api文档,在Editor模式下(项目非运行中)无法使用Destroy()方法, 可以使用DestroyImmediate(),它的第二个参数控制是否可删除资源,默认为false,正好可利用它对搜到的对象进行过滤,以达到只删场景中物体的效果。
注意点击按钮删除游戏物体后无法通过Ctrl+Z恢复。

3,自制Editor窗口

接下来做一个编辑模式下的窗口,在窗口中实现与扩展这个功能。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class LiusCustomEditor : EditorWindow {

	[MenuItem("LiusTool/ShowWindow")]
	public static void ShowWindow(){
		EditorWindow.GetWindow (typeof(LiusCustomEditor));
	}

	void OnGUI(){
		GUILayout.Label ("LiusTool", EditorStyles.boldLabel);
		if(GUILayout.Button("Delete 'H2 (1)'")){
			Delete_H2_1();
		}
	}
	
	void Delete_H2_1(){
		Transform[] CUs=Resources.FindObjectsOfTypeAll<Transform> ();
		foreach (Transform temp in CUs) {
			if (temp.name == "H2 (1)") {
				DestroyImmediate (temp.gameObject);
			}
		}
	}
}

利用MenuItem特性做一个Editor上方目录按钮来弹出该窗口,静态方法中调用EditorWindow.Getwindow()弹出窗口。
实现窗口的类必须继承自EditorWindow,并且此脚本需要放入Assets中的Editor文件夹,在OnGUI()方法中可以对窗口进行自由设计。

这里写图片描述
(图3:一个自制窗口)

4,在自制窗口中实现搜索任意名称游戏物体

以上实现了一个最基础的自制窗口,闲杂扩展一下,加一个搜寻并删除任意名称的游戏物体的功能,并增加一个是否删除非激活游戏物体的可选项:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class LiusCustomEditor : EditorWindow {

	private string itemsToBeDeleted;
	private bool groupEnabled;
	//此变量控制是否删除非开启的游戏物体
	private bool Delete_Items_Dont_Delete_Inactive = false;

	[MenuItem("LiusTool/ShowWindow")]
	public static void ShowWindow(){
		EditorWindow.GetWindow (typeof(LiusCustomEditor));
	}

	void OnGUI(){
		GUILayout.Label ("LiusTool", EditorStyles.boldLabel);
		
		itemsToBeDeleted=EditorGUILayout.TextField ("Delete the items named:", itemsToBeDeleted);

		if(GUILayout.Button("Delete:"+itemsToBeDeleted)){
			Delete_Items(itemsToBeDeleted);
		}
		//可用BeginToggleGroup+EndToggleGroup方法实现"可选项"。
		groupEnabled = EditorGUILayout.BeginToggleGroup ("Optional Settings", groupEnabled);
			//可选项内容
		Delete_Items_Dont_Delete_Inactive = EditorGUILayout.Toggle ("Dont delete inactive items", Delete_Items_Dont_Delete_Inactive);
		EditorGUILayout.EndToggleGroup ();
		//关闭可选项后的逻辑
		if (!groupEnabled) {
			Delete_Items_Dont_Delete_Inactive = false;
		}
	}
	
	void Delete_Items(string name){
		if (name == null) {
			return;
		}
		Transform[] CUs=Resources.FindObjectsOfTypeAll<Transform> ();
		foreach (Transform temp in CUs) {
			if (!Delete_Items_Dont_Delete_Inactive) {
				if (temp.name == name) {
					DestroyImmediate (temp.gameObject);
				}
			} 
			else {
				//只删除为开启状态的游戏物体
				if (temp.name == name&&temp.gameObject.activeInHierarchy) {
					DestroyImmediate (temp.gameObject);
				}
			}
		}
	}
}

这里写图片描述
(图4:扩展功能后的自制窗口,可搜索删除任意名字游戏物体)

上图状态下点击按钮将会删除所有名为111并为激活状态下的游戏物体。


维护日志:
2020-8-4:review

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值