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