【Unity3D】資源管理

2023-10-21 18:02:14

1 前言

​ Unity 中資源管理方案主要有 Resources、TextAsset、ScriptableObject 、AssetDatabase、PlayerPrefs、Addressables、AssetBundle、SQLite,本文將介紹其中大部分方案。

2 Resources

​ 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);
    }
}

3 TextAsset

​ 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);
        }
    }
}

​ 列印如下。

4 ScriptableObject

​ 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 視窗可以調整屬性,如下。

5 AssetDatabase

​ AssetDatabase 用於載入資源,僅在 Unity 編輯器模式下使用,官方介紹見→AssetDatabaseBatching 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 物件。

6 PlayerPrefs

​ 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"));
    }
}

​ 列印紀錄檔如下。

7 Addressables

​ 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】資源管理