Xlua中LuaBehaviour的實現

簡介

  在基於lua進行熱更新的項目中,咱們一般會經過luaBehaviour來讓lua文件模擬MonoBehaviour,可讓lua文件擁有一些MonoBehaviour的生命週期,如Enable、Disable、Update。
  同時能夠注入一些UnityEngine.Object。在lua中方便的調用Unity中的對象。方便開發者進行開發。
  本文進行介紹的luaBehaviour就是基於這個思路設計的,除了上面提到的特性以外還經過Json支持了更多類型的注入,Editor界面更人性化的展現,整個開發過程更接近MonoBehaviour的開發體驗。git

使用

1.新建繼承LuaBehaviour的lua文件,經過AddDefineList添加須要序列化的信息。

2.直接把這個lua文件拖到CS中的LuaBehaviour上便可。


  接下來能夠像MonoBehaviour同樣對數據進行編輯了。
github

實現

腳本的序列化

  luaBehaviour在使用的時候通常是經過記錄名字或路徑的方式來序列化lua文件的的。打包後經過這個路徑從AssetBundle中進行lua文件的加載(這個是lua腳本熱更新經常使用的策略,在這邊就很少說了)。
  這裏仍是經過路徑來記錄lua文件,可是不須要手動輸入,而是經過直接拖動的方式間接記錄lua文件路徑。函數

注入的方式

  不經過C#側定義註冊信息,而是經過在Lua中先定義好要註冊的類型和名稱(更符合MonoBehaviour的開發姿式)。開發時,Editor讀取lua中定義的類型和名稱信息,展現在Inspector中,供開發者編輯。
  在運行時再將序列化的數據注入到lua實例中。工具

序列化的實現

UnityEngine.Object類型對象的序列化

  這種類型沒啥特別的,在LuaBehaviour腳本中定義一個記錄key和UnityEngine.Object的List便可。測試

其餘類型的序列化

  非UnityEngine.Object類型就沒有一個統一的格式,沒法經過一個列表簡單的進行記錄。可是咱們查看Prefab的實例能夠發現,Prefab序列化的數據其實和Json很像。對在MonoBehaviour中定義的各個字段的序列化姿式也和Json很像。

  因此這裏考慮使用Json來序列化非UnityEngine.Object類型的對象。恰好Unity由提供了一套簡單高效的Json工具JsonUtility。JsonUtility內部就是經過Unity serializer實現的,因此穩定性頗有保證。
  可是JsonUtility有個缺點,只能序列化一部分類型,不能序列化如Int、List這種類型。
  爲了解決這個問題。這裏在序列化的時候經過泛型爲每一個類型生成一個Wrap類型。便可通用的實現各類類型的序列化。
ui

注入的實現

UnityEngine.Object類型對象的注入

  也沒啥好說的,直接根據key向Lua實例中Set便可。lua

其餘類型的注入

  先實例化爲Wrap對象,而後再取出其中的須要注入的對象,Set到Lua對象中便可。設計

Inspector界面中的展現

UnityEngine.Object類型對象的展現

  UnityEngine.Object類型統一使用EditorGUILayout.ObjectField繪製便可。對象

其餘類型的展現

  由於沒有找到一個通用的能夠表現全部對象的繪製方式,因此這裏也作了一個轉換。先經過Emit生成一個繼承自ScriptableObject的類(由於ScriptableObject是UntiyEngine.Object,因此可使用SerializedObject來繪製。同時能夠直接經過ScriptableObject.CreateInstance進行實例的建立)。把須要繪製的對象放到這個類裏面,而後經過EditorGUILayout.PropertyField繪製便可。blog

Enable、Update等函數的調用

  這裏把Update、FixedUpdate等高頻或者不多使用的函數拆分出去,只有在Lua中定義了這些函數,才添加對應的Assistant腳本對這些函數進行調用。

  Enable、Disable、Destroy這三個經常使用函數,就直接放在LuaBehaviour腳本中進行調用。

Tips

  1. 這篇文章只起到大體思路和關鍵點的說明,具體細節能夠直接看代碼,代碼比較少也比較清晰。
  2. 經過Wrap的方式序列化各類對象的方式其實也能夠考慮用到一些用戶數據在客戶端的持久化。
  3. 由於這邊主要展現LuaBehanviour的功能,因此AssetBundle的生成和從AssetBundle中加載lua文件都寫得很臨時,僅做展現用。
  4. 打包測試以前要用AssetBundles->Build AssetBundle For Lua生成一下bundle。

項目連接:https://github.com/blueberryzzz/LuaBehaviour

相關文章
相關標籤/搜索