1. 程式人生 > >Unity3d進階學習(8)-- 自定義資源配置檔案、序列化

Unity3d進階學習(8)-- 自定義資源配置檔案、序列化

一、資源配置檔案、序列化的介紹

資源配置檔案:在遊戲開發中,經常會用到一些配置檔案儲存一些資料,然後專案執行中讀取這些配置檔案中的資料在遊戲中使用。比如 XML、JSON、Protobuf、Excel、TXT等等。

序列化:就是將資料的狀態資訊轉換為可以儲存或傳輸的形式的過程。比如將遊戲裡面的資料寫進檔案裡, 包括角色的生命, 攻擊, 防禦等等. 這樣當遊戲需要調整時 (比如平衡性問題), 就只需要對檔案進行改寫, 而不需要將遊戲進行重新編譯. 玩家在更新的時候也只需要下載幾個被改寫的檔案即可.

1.變數 –> 2.序列化格式資料 –> 3.儲存為檔案到硬碟 –> 4.載入檔案 –> 5.讀取序列化格式資料 –> 6.變數
1到2就是序列化,5到6就是反序列化

二、unity的自定義配置檔案

接下來說下使用可序列化類儲存配置,介紹一個Unity的配置檔案(.asset)。
優點:當我們需要將遊戲資源裡的貼圖(Texture)、遊戲物件(Gameobject)等預設體儲存到配置檔案時,這時我們就可以使用該配置檔案,但是當關聯的預設體丟失時,需要重新將預設體關聯起來。

三、通過案例深入理解

下面做一個小案例
1. 玩家通過滑鼠點選螢幕創建出不同的物件(玩家通過配置檔案自定義),創建出來的物件通過資源池進行管理
2. 每個類都有詳細介紹,可以根據需求直接使用

建立序列化類資源池類【GameObjectPool】– 儲存遊戲資源
1. 該類宣告為 [Serializable]
2. 需要序列化的變數將其設定為public或者設定其屬性為[SerializeField]

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

[Serializable]
public class GameObjectPool {
    [SerializeField]
    private string m_name;
    [SerializeField]
    private GameObject m_perfab;
    [SerializeField]
    private int m_maxAmount;

    public
string name { get { return m_name; } } public GameObject gameobject { get { return m_perfab; } } public int maxAmount { get { return m_maxAmount; } } // [NonSerialized] private List<GameObject> m_gameObjList = new List<GameObject>(); public List<GameObject> gameObjList { get { if(m_gameObjList == null) { m_gameObjList = new List<GameObject>(); } return m_gameObjList; } } //如果要優化,可以在建立一個list用來存放Active為false的物體,需要的時候直接獲取就不用遍歷了 public GameObject GetObject() { foreach(GameObject obj in m_gameObjList) { if (!obj.activeInHierarchy) { obj.SetActive(true); return obj; } } if(m_gameObjList.Count >= m_maxAmount) { GameObject.Destroy(m_gameObjList[0]); m_gameObjList.RemoveAt(0); } GameObject prefab = GameObject.Instantiate(m_perfab, new Vector3(0, 3, 0), Quaternion.identity); m_gameObjList.Add(prefab); return prefab; } }

儲存所有資源池的類【GameObjectPoolList】 – 建立該類為配置檔案
1. 類必須繼承 ScriptableObject

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 儲存所有的資源池  繼承ScriptableObject變成可自定義的資源配置檔案
/// </summary>
public class GameObjectPoolList: ScriptableObject
{
    [SerializeField]
    private List<GameObjectPool> m_poolList = new List<GameObjectPool>();
    public List<GameObjectPool> poolList
    {
        get
        {
            if(m_poolList == null)
            {
                m_poolList = new List<GameObjectPool>();
            }
            return m_poolList;
        }
    }
}

管理資源池的類【PoolManager】 – 外界通過訪問這個類來訪問資源池

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PoolManager {

    private static PoolManager m_instance = null;
    public static PoolManager Instance
    {
        get
        {
            if(m_instance == null)
            {
                m_instance = new PoolManager();
            }
            return m_instance;
        }
    }

    //檔案路徑
    private const string m_pathPrefix = "Assets/FrameWork/Resources/";
    private const string m_fileName = "Gameobjectpool";
    private const string m_pathPostfix = ".asset";
    public static string PoolConfigPath
    {
        get
        {
            return m_pathPrefix + m_fileName + m_pathPostfix;
        }
    }
    //字典  根據name查詢對應的pool
    private Dictionary<string, GameObjectPool> m_poolDic;

    //建構函式
    PoolManager()
    {
        GameObjectPoolList poolList = Resources.Load<GameObjectPoolList>(m_fileName);//獲取檔案類

        m_poolDic = new Dictionary<string, GameObjectPool>();
        foreach(GameObjectPool pool in poolList.poolList)
        {
            m_poolDic.Add(pool.name, pool);
        }
    }

    public void Init()
    {
        //do nothing
    }

    public GameObject GetObjectFromPool(string poolName)
    {
        GameObjectPool pool;
        if(m_poolDic.TryGetValue(poolName, out pool))
        {
            return pool.GetObject();
        }
        else
        {
            Debug.LogWarning("poolName: " + poolName + "  is not exit");
            return null;
        }
    }
}

建立配置檔案的類 【PoolManagerEditor】– 利用編譯器方法建立 GameObjectPoolList 為配置檔案
1. 工程下新建一個資料夾 Editor,在該資料夾下建立下面的類
2. 選單欄中找 Manager –> Create GameObjectPoolConfig 點選執行就可以 PoolManager.PoolConfigPath 的路徑下看到生成的配置檔案

public class PoolManagerEditor
{
    //將這個方法做成一個選單
    [MenuItem("Manager/Create GameObjectPoolConfig")]
    static void CreatePoolList()
    {
        //將物件例項化
        GameObjectPoolList poolList = ScriptableObject.CreateInstance<GameObjectPoolList>();

        //建立類為可編輯的配置檔案
        AssetDatabase.CreateAsset(poolList, PoolManager.PoolConfigPath);
        AssetDatabase.SaveAssets();
    }
}

四、測試

1. 通過配置檔案,自行配置資源
這裡寫圖片描述

2. 程式碼測試

private void Update()
{
   if (Input.GetMouseButtonDown(0))
   {
      GameObject obj = PoolManager.Instance.GetObjectFromPool("Sphere");
   }
}