平常我們是用手動拖拉的方式在 Inspector 中設定腳本所需的預製物件,當資料量一多時,手動操作會拖慢開發進度,所以這部分應該要設計成自動化的機制。
AssetDatabase 這個類別依賴在 UnityEditor 命名空間下,意味著這個方法只能在編輯器環境下運作,不可部署到正式執行環境中,所以我們不能用這篇說明的手法來達到 Asset 資源的動態載入 (請左轉 Addressable)。
在這篇文章中,我們將會使用到 AssetDatabase 類別下的 FindAssets、LoadAssetAtPath、GUIDToAssetPath 三個方法,並搭配 System.Linq 語法完成自動化功能。
AssetDatabase.FindAssets
FindAssets 顧名思義就是搜尋專案資產,也就是 Assets 資料夾內的所有東西。他需要輸入的參數為字串,我們可以直接在 Project 視窗中測試搜尋字串的語法:

字串中的 t 代表 Type,假設我們要搜尋的 Prefab 或 ScriptableObject 中帶有 ItemData 類別,可以輸入:
string[] itemGUIDs = AssetDatabase.FindAssets($"t:{nameof(ItemData)}");
如果 FindAssets 有找到物件,將會以字串陣列方式回傳物件的 GUID。
AssetDatabase.LoadAssetAtPath
LoadAssetAtPath 就更簡單了,只要在輸入的參數中給予正確的路徑,此方法將會回傳目標物件給你。
例如:
ItemData item = AssetDatabase.LoadAssetAtPath<ItemData>("Assets/Settings/Item Data 1.asset");
AssetDatabase.GUIDToAssetPath
GUIDToAssetPath 函式是一個轉換器,可以將輸入的 GUID 字串轉為物件的路徑字串,這是我們用來完成這個自動化機制的重要核心。
自動化載入語法
一開始我們需要使用 #if 語法來確保其中的程式碼只會在編輯器環境下運作,所以要分別將 using UnityEditor 與 OnValidate 用 #if UNITY_EDITOR 包起來。
接下來將按照以下流程完成物件搜尋作業:
- 在 OnValidate 中透過 FindAssets 找到物件的 GUID。
- 透過 Linq 的 Select 將 GUID 提取出來。
- 透過 GUIDToAssetPath 將物件 GUID 轉換為路徑。
- 透過 LoadAssetAtPath 將物件路徑轉為物件本身。
- 使用 ToArray 將所有結果轉為物件陣列。
using UnityEngine;
using System.Linq;
#if UNITY_EDITOR
using UnityEditor;
#endif
public class GameManager : MonoBehaviour
{
public ItemData[] items;
#if UNITY_EDITOR
private void OnValidate()
{
items =
AssetDatabase.FindAssets($"t:{nameof(ItemData)}")
.Select(x => AssetDatabase.LoadAssetAtPath<ItemData>(AssetDatabase.GUIDToAssetPath(x)))
.ToArray();
}
#endif
}
雖然這串語法又臭又長,但其實你可以將它變成一個泛型的方法,也可以用靜態類別的方式以便未來使用:
using UnityEngine;
using System.Linq;
#if UNITY_EDITOR
using UnityEditor;
#endif
public static class AssetExtension
{
public static T[] FindAllAssets<T>() where T : Object
{
return AssetDatabase.FindAssets($"t:{typeof(T).Name}")
.Select(x => AssetDatabase.LoadAssetAtPath<T>(AssetDatabase.GUIDToAssetPath(x)))
.ToArray();
}
}
只要呼叫 AssetExtension.FindAllAssets 方法即可搜尋物件:
#if UNITY_EDITOR
private void OnValidate()
{
items = AssetExtension.FindAllAssets<ItemData>();
}
#endif
Inspector 結果:

將這些可以加速開發的語法好好記錄起來,當未來需要用到相同功能時就可以直接派上用場。