遊戲底層資源管理載入框架(一) ------ 架構以及預備知識
阿新 • • 發佈:2018-12-12
一.架構
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);
}
}