1. 程式人生 > >遊戲底層資源管理載入框架(一) ------ 架構以及預備知識

遊戲底層資源管理載入框架(一) ------ 架構以及預備知識

一.架構

1. AssetBundle打包管理

2.類物件池資源池物件池 打包管理ssetBundle打包管理

3.離線資料及配置表

4.使用框架製作簡單的UI系統

預備知識 :

1.程式集

2.unity資源載入方式介紹 

3.c#的xml序列化  

4.unity asset序列化

二.程式集

unity2017.3之後可以自定義程式集,方便解耦,專案中一些底層的東西可以打包以方便跨平臺使用,新建test指令碼:

 該dll生成目錄為(2018之後還會預設生成一些dll) :

 自定義程式集 :

你會發現先前建立的test.cs會屬於新建立的test1.dll,之前預設的dll也不見了:

也就是說,新建的 dll會包含同級目錄以及子目錄中的指令碼(不會包含同級資料夾中的指令碼,總的來說就是就近原則,以資料夾區分)

我們都知道沒有引用一個庫(using),是無法呼叫其中的指令碼的,當自定義程式集想要引用其他自定義的程式集時,需要新增依賴,這樣我們可以自定義程式集之間的依賴關係

而預設程式集(Assembly-CSharp.dll)是自動依賴所有自定義的程式集,不需手動新增依賴

 

三.資源載入

 1.拖到元件上(商業基本不會用)   

 2.Resources.load  

         商用不常用,Resources底下資源是有限的,大概2個G,一般放配置表之類的

 3.AssetBundle (商用模式常用,比Resources.load 效率高,佔用記憶體小)

     ①.打包

public class BundleEditor : MonoBehaviour {

	[MenuItem("Tool/打包")]
    public static void Build()
    {
        //將AB打包在StreamingAssets資料夾下,注意先建立該資料夾
        BuildPipeline.BuildAssetBundles(Application.streamingAssetsPath,
            BuildAssetBundleOptions.ChunkBasedCompression,EditorUserBuildSettings.activeBuildTarget); 
        AssetDatabase.Refresh(); //編輯器的重新整理
    }
}

 將要打包的資源進行AB命名:

 Tool - 打包 :

   ②.訪問

void Start () {
        AssetBundle assetBundle = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/abtest.aaa");
        GameObject gameObject = Instantiate(assetBundle.LoadAsset<GameObject>("attack"));
	}

  4.AssetDataBase.LoadAtPtah(編輯器程式碼,遊戲執行不會使用的)

  //Assets目錄下的相對路徑,要加上字尾
        //主要用於在編輯器中用程式碼更改本地檔案
        GameObject gameObject = Instantiate(
            UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>("Assets/GameData/Prefabs/Attack.prefab"));

四.c#的xml序列化  (將一個類序列化本地資料)

1.類與xml相互轉化(實際上不用,太明顯,資料量也大)

需要轉化的類 :

using System.Xml.Serialization;

//需要序列化的類上需要有這個標籤
[System.Serializable]
public class ToXml
{ //注意不要繼承MonoBehaviour
    [XmlAttribute("id")]
    public int id;
    [XmlElement("list")]//也可以用XmlArray
    public List<int> list { get; set; }
}

類轉xml :

using System.Xml.Serialization;

public class LoadFromStreamingFile : MonoBehaviour {
	void Start () {
        OnSerialize();
    }

	void Update () {
		
	}

    public void OnSerialize()
    {
        ToXml toXml = new ToXml();
        toXml.id = -1;
        toXml.list = new List<int>();
        toXml.list.Add(1);
        toXml.list.Add(2);
        xmlSerialize(toXml);
    }
    public void xmlSerialize(ToXml toxml)
    {
        FileStream fileStream = new FileStream(Application.dataPath + "/test.xml",FileMode.Create,FileAccess.ReadWrite,
           FileShare.ReadWrite ); //開啟檔案流
        StreamWriter sw = new StreamWriter(fileStream,System.Text.Encoding.UTF8);  //開啟寫入流
        XmlSerializer xmlSerializer = new XmlSerializer(toxml.GetType()); //需要傳入序列化類的型別
        xmlSerializer.Serialize(sw, toxml);
        //關閉
        sw.Close();
        fileStream.Close();
    }
}

轉化之後:

 xml檔案轉類:

  public void DeSerialize()
    {
        ToXml toXml = xmlDeSerialize();
        Debug.Log(toXml.id);
        foreach(int i in toXml.list)
        {
            Debug.Log(i);
        }
    }
public ToXml xmlDeSerialize()
    {
        Debug.Log(Application.dataPath + "/test.xml");
        FileStream fileStream = new FileStream(Application.dataPath + "/test.xml", FileMode.Open, FileAccess.ReadWrite,
           FileShare.ReadWrite); //開啟檔案流
        XmlSerializer xmlSerializer = new XmlSerializer(typeof(ToXml)); //需要傳入序列化類的型別
        ToXml toXml = (ToXml)xmlSerializer.Deserialize(fileStream);
        fileStream.Close();
        return toXml;
    }

2.類轉成二進位制

序列化:

  public void OnBinarySerialize()
    {
        ToXml toXml = new ToXml();
        toXml.id = -1;
        toXml.list = new List<int>();
        toXml.list.Add(1);
        toXml.list.Add(2);
        BinarySerilizer(toXml);
    }
   public void BinarySerilizer(ToXml toXml)
    {
        Debug.Log(Application.dataPath);
        FileStream fileStream = new FileStream(Application.dataPath + "/test.bytes", FileMode.Create, FileAccess.ReadWrite,
           FileShare.ReadWrite); //開啟檔案流
        BinaryFormatter bf = new BinaryFormatter();
        bf.Serialize(fileStream, toXml);
        fileStream.Close();
    }

反序列化:

   public void DeBinarySerialize()
    {
       ToXml toXml = BinaryDeSerialize();
        Debug.Log(toXml.id);
        foreach (int i in toXml.list)
        {
            Debug.Log(i);
        }
    }
public ToXml BinaryDeSerialize()
    {
        TextAsset textAsset = UnityEditor.AssetDatabase.LoadAssetAtPath<TextAsset>("Assets/test.bytes");
        MemoryStream stream = new MemoryStream(textAsset.bytes);
        BinaryFormatter bf = new BinaryFormatter();
        ToXml toXml = (ToXml)bf.Deserialize(stream);
        stream.Close();
        return toXml;
    }

五.unity asset序列化 ScriptableObject

[CreateAssetMenu(fileName ="TestAssets",menuName = "CreateAssets",order = 0)]
public class AssetSerialize : ScriptableObject {
    public int id;
    public List<string> TestList;
	
}

 

注意dictionary是序列化不好的,一般使用兩個list儲存

    public void ReadTestAssets()
    {
        AssetSerialize assetSerialize = UnityEditor.AssetDatabase.LoadAssetAtPath<AssetSerialize>
            ("Assets/1.架構以及預備知識/scripts/TestAssets.asset");
        Debug.Log(assetSerialize.id);
        foreach (string i in assetSerialize.TestList)
        {
            Debug.Log(i);
        }
    }