首先要明確的問題
Unity自帶的Serializable特性無法對GameObject進行初始化,幾乎沒有任何意義
EsaySave插件可以對遊戲內的數據包括Gameobject進行序列化,但是實際使用情況沒有經過測試
GUID
Unity引擎本身生成的GUID本身不保存任何數據,只是作爲一個索引,實際數據存在Library/matedata文件夾裏,用GUID頭兩位劃分文件夾,以GUID作爲文件名,後綴名爲info,將文件路徑等屬性存在info文件裏,其中,GUID只作爲映射對應文件所需要的索引
info文件對中文采用Unicode編碼
生成的GUID是緩存在內存中的,如果文件被刪除,GUID及對應的meta文件及info文件會被刪除,但是如果之後又復原了,那麼Unity會重新生成一份一模一樣的GUID及Mate文件info文件,前提是文件本身沒發生變化,如果刪除了文件又關閉了Unity,那麼下次打開Unity的時候再導入同一個文件,就會重新生成一個新的GUID及對應的文件
MateData文件夾的排序順序:0>字母>1~9
GUID及LocalID(FileID)的創建和使用依賴AssetDataBase類,依賴於Unity3D Editor.dll,所以這一切無法在運行時使用
綜上所述,如果我們想在遊戲運行時進行序列化保存工作,將無法使用Unity序列化及資源管理的任何特性!但是我們可以從Unity的設計思路中獲取到一些我們需要的,可行的保持依賴的方法
之所以需要一個額外的GUID和FileID來映射對應的文件夾,是爲了保證資源放在Assets文件夾下的任何位置都可以被索引到
FileID(LocalID)
確保在同一個資源文件(模型,圖集等)下,所有的對象都有唯一的ID
32位int類型
生成規則:文件的MD4編碼的前四位byte+字符串"s\0\0\0"+類的命名空間+類名
UnityPrefab
prefab文件並不存儲具體資源,而是使用了yaml語言描述了一個被序列化的GameObject對象中包含的所有GameObject,Component的信息。包括相互之間的關係、存儲的數據和引用信息。
就像這樣:
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &6661200084521074333
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 6661200084521074330}
- component: {fileID: 6661200084521074329}
- component: {fileID: 6661200084521074328}
- component: {fileID: 6661200084521074331}
m_Layer: 9
m_Name: Sphere
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &6661200084521074330
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6661200084521074333}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 1.496, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 6661200085399109717}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
其中最關鍵的一行
--- !u!1 &6661200084521074333
!u! 1描述了這是種什麼組件,詳細的可以在這裏看到
&6661200084521074333
這裏描述了這個Component的FileID,在Unity裏,任何物體都有Gameobject及Transform兩個Component,每個Component都會有一個在當前資源文件中唯一的FileID
m_Component:
- component: {fileID: 6661200084521074330}
- component: {fileID: 6661200084521074329}
- component: {fileID: 6661200084521074328}
- component: {fileID: 6661200084521074331}
代表了這個GameObject上有多少個Component,只包含了當前預製體的當前物體所有的Component,如果一個預製體下有多個GameObject,會分別記錄在不同的GameObjectComponent上
m_Father: {fileID: 6661200085399109717}
Transform的父物體的FileID
UnityScene
Scene的序列化和Prefab沒有太多差距,主要是將一些場景的設置當作Component(或者本身就是Component)存了起來,如下:
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 9
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 2100000, guid: c8e304140c860744783e1aa250535791, type: 2}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 170076734}
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
m_UseRadianceAmbientProbe: 0
綜上所述
Unity的資源管理本質是描述文件和索引文件的管理,資源文件具有一個.mate類型的索引文件,其中有AssetbundleName及GUID等
再通過GUID去找描述文件,描述文件裏面有該文件的路徑,設置等
而Prefab和Scene就是把物體序列化了,並通過GUID和FileID查找
這樣就可以保證無論一個資源文件在Assets文件夾下怎麼改動都不會丟失引用
參考資料
https://abaojin.github.io/2017/02/08/unity-project/
https://forum.unity.com/threads/how-to-get-filename-from-the-local-file-id.693103/
https://www.cnblogs.com/blueberryzzz/p/9097391.html
https://forum.unity.com/threads/yaml-fileid-hash-function-for-dll-scripts.252075/