天天看點

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(){
	}
}

           
Unity Editor自制工具(1)--“Editor目錄欄按鈕+全局搜尋方法+自制Editor視窗”實作搜尋與删除場景中任意名稱遊戲物體

(圖1:利用MenuItem特性實作上Editor上方目錄按鈕)

2,非運作狀态下對項目中所有對象進行全局搜尋

假如在場景中有很多gameObject,而它們又都有很複雜的父子物體結構(如下圖),如果在Editor中想對它們進行批量修改是很麻煩的,沒法全部圈選。可選擇用腳本寫代碼進行操作,這時可以調用Resources.FindObjectsofTypeAll<>方法。

Unity Editor自制工具(1)--“Editor目錄欄按鈕+全局搜尋方法+自制Editor視窗”實作搜尋與删除場景中任意名稱遊戲物體

(圖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()方法中可以對視窗進行自由設計。

Unity Editor自制工具(1)--“Editor目錄欄按鈕+全局搜尋方法+自制Editor視窗”實作搜尋與删除場景中任意名稱遊戲物體

(圖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);
				}
			}
		}
	}
}
           
Unity Editor自制工具(1)--“Editor目錄欄按鈕+全局搜尋方法+自制Editor視窗”實作搜尋與删除場景中任意名稱遊戲物體

(圖4:擴充功能後的自制視窗,可搜尋删除任意名字遊戲物體)

上圖狀态下點選按鈕将會删除所有名為111并為激活狀态下的遊戲物體。

維護日志:

2020-8-4:review