Unity 中資源管理方案主要有 Resources、TextAsset、ScriptableObject 、AssetDatabase、PlayerPrefs、Addressables、AssetBundle、SQLite,本文將介紹其中大部分方案。
Resources 主要用於載入資源,被載入的資源需要放在 Resources 目錄下,可以在 Assets 的任何子目錄下建立 Resources 目錄,Unity 會自動檢索到這些 Resources 目錄。
Test_Resources.cs
using UnityEngine;
public class Test_Resources : MonoBehaviour {
private void Awake() {
GameObject cube = Resources.Load<GameObject>("CubePrefab");
Material cubeMat = Resources.Load<Material>("CubeMat");
cube.GetComponent<Renderer>().material = cubeMat;
Instantiate(cube);
}
}
TextAsset 主要用於載入文字、表格檔案,官方介紹見→TextAsset。
Test_TextAsset.cs
using UnityEngine;
public class Test_TextAsset : MonoBehaviour {
[SerializeField]
private TextAsset heightDatas;
private void Awake() {
string[] textInLines = heightDatas.text.Split('\n');
for (int i = 1; i < textInLines.Length; i++) {
string[] values = textInLines[i].Split(",");
string name = values[0];
int age = int.Parse(values[1]);
float height = float.Parse(values[2]);
Debug.Log("name=" + name + ", age=" + age + ", height=" + height);
}
}
}
列印如下。
ScriptableObject 主要用於持久化資料、專案引數設定、角色引數設定等,官方介紹見→ScriptableObject,主要回撥函數如下,繼承 ScriptableObject 後,重寫下述方法即可在相應狀態下自動回撥。
SOData.cs
using UnityEngine;
public class SOData : ScriptableObject {
[SerializeField]
private string _name; // 姓名
[SerializeField]
private int _age; // 年齡
[SerializeField, Range(1f, 2.3f)]
private float _height; // 身高
public string Name => _name;
public int Age => _age;
public float Height => _height;
}
編譯後,在 Assets 視窗右鍵,依次選擇【Create→SOData】,建立物件,並重新命名為 SOData_1。選中 SOData_1 物件後,在 Inspector 視窗可以調整屬性,如下。
AssetDatabase 用於載入資源,僅在 Unity 編輯器模式下使用,官方介紹見→AssetDatabase、Batching with the AssetDatabase。
AssetDatabase.CopyAsset("Assets/Asset1.txt", "Assets/Text/Asset1.txt"); // 複製資源
AssetDatabase.MoveAsset("Assets/Asset2.txt", "Assets/Text/Asset2.txt"); // 移動資源
AssetDatabase.DeleteAsset("Assets/Asset3.txt"); // 刪除資源
AssetDatabase.ImportAsset(path1, ImportAssetOptions.Default); // 匯入資源
GameObject cube = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Loader/CubePrefab.prefab"); // 載入資源
Test_AssetDatabase.cs
using UnityEditor;
using UnityEngine;
public class Test_AssetDatabase {
[MenuItem("Custom/Import Cube")]
public static void ImportImage() {
// 匯入Cube預設體
string path1 = "Assets/Loader/CubePrefab.prefab";
AssetDatabase.ImportAsset(path1, ImportAssetOptions.Default);
GameObject cube = AssetDatabase.LoadAssetAtPath<GameObject>(path1);
// 匯入Cube材質
string path2 = "Assets/Loader/CubeMat.mat";
AssetDatabase.ImportAsset(path2, ImportAssetOptions.Default);
Material mat = AssetDatabase.LoadAssetAtPath<Material>(path2);
// 範例化Cube
cube.GetComponent<Renderer>().material = mat;
GameObject.Instantiate(cube);
}
}
說明:Test_AssetDatabase 指令碼檔案需要放在 Editor 目錄下面。編譯後,在選單欄依次點選【Custom→Import Cube】即可建立一個 Cube 物件。
PlayerPrefs 是一個在遊戲對談之間儲存玩家偏好的類,它可以將字串、浮點數和整數值儲存到使用者的平臺登入檔中。Unity 將 PlayerPrefs 儲存在本地登入檔中,沒有加密,不要使用 PlayerPrefs 資料儲存敏感資料。PlayerPrefs 官方介紹見→PlayerPrefs。
PlayerPrefs 的靜態方法如下。
Test_PlayerPrefs.cs
using UnityEngine;
public class Test_PlayerPrefs : MonoBehaviour {
private void Awake() {
PlayerPrefs.SetString("name", "Zhang san");
PlayerPrefs.SetInt("age", 25);
PlayerPrefs.SetFloat("height", 1.75f);
Debug.Log("name=" + PlayerPrefs.GetString("name")
+ ", age=" + PlayerPrefs.GetInt("age")
+ ", height=" + PlayerPrefs.GetFloat("height"));
}
}
列印紀錄檔如下。
Addressables 包提供了組織和打包應用內容的工具和指令碼,在執行時可以載入和釋放資源,官方介紹見→Addressables。
1)安裝 Addressables
在選單欄依次選擇【Window→Package Manager】,開啟包管理器,按照以下步驟安裝 Addressables。
2)設定資源為 Addressable
在 Assets 視窗選中資源,在 Inspector 視窗勾選 Addressable,並修改資源 Key,如下。
3)分組管理 Addressables
在選單欄依次選擇【Window→Asset Management→Addressables→Groups】,開啟 Addressables Groups 視窗,如下。
可以拖拽 Addressables Groups 視窗,使其停靠在 Game 視窗旁邊,如下。可以看到 Resources 目錄下的資源會自動新增到 Addressables 中。
依次點選【New→Packed Assets】,建立新包,並重新命名,便於對資源進行分組管理,如下。
4)載入資源
Test_Addressables.cs
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
public class Test_Addressables : MonoBehaviour {
private GameObject cube;
private void Awake() {
Addressables.InstantiateAsync("CubePrefab2").Completed += OnInstantiate;
}
private void OnInstantiate(AsyncOperationHandle<GameObject> operationHandle) { // 遊戲物件載入成功回撥函數
cube = operationHandle.Result;
Addressables.LoadAssetAsync<Material>("CubeMat2").Completed += OnLoadAsset;
}
private void OnLoadAsset(AsyncOperationHandle<Material> operationHandle) { // 材質載入成功回撥函數
cube.GetComponent<Renderer>().material = operationHandle.Result;
}
}
說明:引入 UnityEngine.AddressableAssets 和 UnityEngine.ResourceManagement.AsyncOperations 這兩個名稱空間時,在 VSCode 中可能會報錯,但 Unity 中不會報錯,也不影響程式執行。如果想消除 VSCode 中的這個報錯,可以重啟一下 Unity 和 VSCode,就不會報錯了。
宣告:本文轉自【Unity3D】資源管理。