Unity動態(Runtime)加載腳本

之前在羣裏跟人談到腳本更新問題,於是就突然發現因爲U3D對資源進行了打包,所以很難更新資源。說實在,我現在還沒找到資源更新的辦法,不過知道了資源可以從網絡下載實時加載。後來看到有人說可以動態加載腳本,於是就去研究了。途中各種蛋疼不提也罷。其實基本原理就是使用到了C#的反射,熟悉反射的應該很簡單就能解決。


var fs = new FileStream(@"D:\Personal\My Documents\Projects\TestLib\TestLib\bin\Release\TestLib.dll", FileMode.Open);
        var b = new byte[fs.Length];
        fs.Read(b, 0, b.Length);
        fs.Close();
        var assembly = System.Reflection.Assembly.Load(b);
        var type = assembly.GetType("Test");
        gameObject.AddComponent(type);

分析這段代碼

加載裏一個DLL,這個DLL實際上是用C#打包的代碼庫,關於對庫的各種叫法實在讓人蛋疼,不提也罷。總之建立一個工程然後引用U3D的庫UnityEngine.dll就可以編譯,不引用UnityEngine.dll當然首先就沒法通過編譯。

我這裏的類名就叫Test,所以獲取類型就是這樣的。這裏添加組件就不能用AddComponent(string)方法,那樣會提示找不到了,可能這個方法只是從字典裏面找到相應的類型然後在用AddComponent(type)來添加。


要吐槽的是關於那個二進制流。看網上很多WWW來讀取TextAsset然後轉成byte[]。事實上我不管怎麼試都是失敗。與乾脆用C#自帶的函數,就實際情況來說雖然統一使用WWW會比較方便,不過即使用C#來做網絡下載難度也不會太大。


最後說缺點。

缺點明顯是這樣的做更新行不通。因爲文件最終沒被保存在本地,下次還要下載,不過你可能會下載先保存在本地再讀取,那樣或許可以,但是我目前還沒有嘗試。

但是如果是某個腳本有BUG想修復,這樣完全就行不通了,這種情況我目前不知道如何處理。有知道的話真想請教請教。

還有個缺點就是因爲不能和現有的類直接依賴。那麼這時候估計就只能靠接口來解決問題了,事實上低依賴就是設計原則,所以這個缺點並不是完全沒辦法解決。


硬要說有什麼優點的話,可能是可以把部分代碼放在服務器,需要的時候才下載下來使用,讓別人有客戶端也沒法運行遊戲。

不過實際上腳本文件會被優先考慮,畢竟體積更小,熱更新也更方便。昨天去看了雲風的博客,他們就做 了個基於C#的LUA實現,不過貌似還不是很完整,也不知道會不會放出完整版。但是能用LUA的話我還是很願意使用LUA,函數式編程相當的有意思。

發佈了61 篇原創文章 · 獲贊 5 · 訪問量 37萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章