Unity3D開發中熱更新為什麼不能使用C 的思考

2021-08-15 21:09:01 字數 1378 閱讀 1571

閱讀了網上一些文章,其實使用c#進行熱更新是可以的,將需要更新的**打包成程式集,然後利用反射即可,但是也提到在ios平台是不行的,至於為什麼不行,就不再說了,然後就是推薦lua作為熱更新方案,但是,為啥lua就行?c#就不行?

好多人都說lua能熱更新,是因為它是解釋型語言,不用編譯,在執行時能動態解釋lua**並執行。這種方法實際上不準確,從某些角度來說是錯的。lua確實是解釋性指令碼語言,但是不是因為是解釋型才能進行熱更新。即使使用c++這種編譯語言,也能進行熱更新,將動態鏈結庫進行更新就是,然後動態載入動態鏈結庫獲取更新的函式位址即可。

而且,還有一點,c#並不能說是一種編譯型語言,c#**會被編譯成il,il解釋成機器碼的過程可以在執行之前進行也能在執行時進行。如果在執行時進行解釋,那麼和lua不就一樣了嗎,為啥c#不能進行熱更新呢?

首先說一下,jit對il如何在執行時進行解釋並執行的,大致過程為:將il解釋為所在平台的機器碼,開闢一段記憶體空間,要求這段記憶體空間可讀、可寫、可執行,然後把解發布的機器碼放入,修改cpu中的指令指標暫存器中的位址,讓cpu執行之前解發布來的機器碼。

注意這段記憶體的條件,最重要的一條是必須是可執行的,一般的記憶體申請我們只是存放資料,但是這裡的記憶體許可權要是有可執行許可權

ios不允許獲取具有可執行許可權的記憶體空間,這就直接要求jit要以full aot模式,這種模式會在生成之前把il直接翻譯成機器碼而不是在執行期間,進行了這種操作c#從某種角度來說和c++一樣,成為了編譯型語言,失去了執行時解釋的功能。

如果lua的解釋執行原理和c#相同,肯定也不能在ios平台上執行時解釋執行。lua是使用c編寫的指令碼語言,它在執行時讀入lua編寫的**,在解釋lua位元組碼(lua自己的指令)時不是翻譯為機器碼,而是使用c**進行解釋,不用開闢特殊的記憶體空間,也不會有新**在執行,執行的是lua的虛擬機器,用c寫出來的虛擬機器,這和c#的機制是完全不同的,因為lua是基於c的指令碼語言。

il虛擬機器支援完全解釋執行,就是效率差一些,具體可以參考使用il runtime進行熱更的方式。只在公司聽過講座分享,有乙個工作室熱更完全使用il runtime方案,開發效率要快不少。

這種方式把c#**分成了要熱更的和不需要熱更的,也就是c#框架層和c#邏輯層,開發時候統一使用c#進行,十分方便,就是在純計算部分的效率上要慢很多,所以計算部分最好還是放在不需要熱更的框架層不進行解釋執行。

unity使用c++開發引擎層,暴露c#介面給開發人員使用以提高開發效率。然後強行加個用c寫的lua層,在lua層呼叫c#介面,轉了一層,c#再呼叫c++介面,再轉一層…

說白了,就是由於lua這種指令碼語言的特性,基於已經存在的某種語言的一種新的語言,這也是指令碼語言和c#、c++這類語言的本質區別。當然,lua虛擬機器不僅可以使用c寫,也可以用c#寫。使用熱更新也不一定非要用lua,python同樣可以,只不過lua短小精悍,本身**長度就不是很大,可以從github上看到。

Unity3D熱更新全書 PageZero

unity3d熱更新全書 何謂熱更新,為何熱更新,如何熱更新 這一篇是寫給對熱更新完全沒概念的人 unity3d熱更新全書 資源載入 一 從assetbundle說起 這一篇是 使用assetbundle來做資源更新的問題,希望能讓更多人理解assetbundle是有害的 unity3d熱更新全書 ...

使用xlua 進行Unity3D 熱更新 2

一接觸到新的東西,總想看看背後的原理是怎樣的,xlua也不例外。於是試著寫了一下,算是了解底層的實現原理,以後不用xlua也能有借鑑的地方。xlua的熱修復原理實際上是在 c 編譯成中間語言的時候,進行 的插入這部分用到了 mono.ceil 庫來操作,當然還有其他很多的庫也可以實現。因為是在il的...

Unity3D開發(九) Unity3d流光效果

遊戲開 壇 hello game 遊戲開發群 201276069 之前曾經注意過material 中紋理的屬性都有 tiling 和offset 但沒有深究過其用途,今天才知道竟然可以利用 offset做uv 動畫,從而完成各種有趣的動畫,比如流光效果!流過效果即通常一條高光光在物體上劃過,模擬高光...