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