為什麼unity只有將數據序列化之後才能顯示再Inspector面板上?

在Inspector面板中顯示的數據可以在程序運行時動態的修改,而其他的數據在修改之後腳本都需要重新編譯,這個原理還不清楚,但是由於數據序列化之後才能在面板中修改,我感覺和它有關係,但我想明白其中詳細的原理。

而且順便問一下,我有的腳本並沒有繼承mono,所以不能在Inspector面板中顯示並在運行時修改其中的數據,每次修改都需要重新運行遊戲很不方便,這個有什麼技術可以解決嘛??


每當你修改腳本,編輯器右下就會轉小圈圈,它提示你腳本在編譯,編譯後的腳本需要重新載入才有效。其實unity本身是一個cpp寫出來得引擎,它只是封裝了一層便於用戶使用得腳本層,這裡主要是指c#。c#是託管語言,它得內存分配對用戶是透明得,你不需要顯示的申請和釋放內存。所以當你c#寫好腳本後,需要讓cpp引擎運行,就必須得有一條路讓託管層面得代碼數據與非託管層面得代碼數據交互。所以當你的腳本重新載入,也就是assembly在reload後,引擎會把你腳本里的數據從託管層傳輸到非託管層。當一個腳本改變後,還涉及到了Assembly的卸載,這就需要把現有的Assembly用到的內存清除掉。有時還需要把cpp端修改的數據保存回Assembly。

[1]Serialization in Unity

[2]Unity Serialization


簡單來說,序列化對象-摧毀mono runtime-編譯-運行新的mono runtime-反序列化對象。你能夠存的數據就在這些可序列化對象的可序列化欄位之中。

你可以創建一個類繼承自ScriptObject,這樣你的數據才能被Unity序列化,但是實際上你可以自定義內部序列化策略,比如使用json:

序列化: 把對象用json庫序列化後存到ScriptObject子類的一個字元串欄位里。

反序列化: 使用json庫對目標欄位進行反序列化,使用UnityEditor.EditorGUILayout等相關api把反序列化後的對象欄位在inspector里顯示。

由於這裡用的是json序列化,所以這些類就可以不需要Serializable屬性或繼承Unity的類。


推薦閱讀:

這四個方塊受的力一樣么?
作為Unity3D的腳本而言,c#中for是否真的比foreach效率更高?
unity3d怎麼用代碼實現縮放粒子特效?
由unity引擎做的遊戲《缺氧》,它的地圖的機制是怎麼實現的?
unity中從Resources下讀取較大的資源會卡,有解決辦法么?

TAG:Unity遊戲引擎 |