ILRuntime是如何與Unity互相調(diào)用的

一院水、ILRuntime的基本介紹

ILRuntime是一個跨平臺CLR實現(xiàn),它可以在多個平臺上運行C#代碼癌幕,包括Android、iOS昧穿、Windows勺远、Linux等等。ILRuntime的實現(xiàn)方式是將C#代碼編譯成IL代碼时鸵,然后在運行時通過JIT或AOT的方式將IL代碼轉(zhuǎn)換為機(jī)器代碼胶逢,從而實現(xiàn)跨平臺的效果。ILRuntime的主要功能包括熱更新饰潜、動態(tài)加載初坠、代碼加密等等。

二彭雾、Unity與ILRuntime的集成

Unity與ILRuntime的集成主要包括以下幾個步驟:

1碟刺、添加ILRuntime的插件

首先需要將ILRuntime的插件添加到Unity項目中,這可以通過Unity Asset Store中搜索“ILRuntime”來獲取薯酝。

2半沽、修改Unity項目的腳本編譯方式

默認(rèn)情況下爽柒,Unity項目中的腳本會被編譯為Mono或IL2CPP,但是為了使用ILRuntime者填,需要將腳本編譯為.NET?Standard 2.0浩村。這可以通過修改Unity項目的Player Settings來實現(xiàn),在Player Settings中選擇“Other Settings”并將“Scripting Runtime Version”設(shè)置為.NET?4.x Equivalent占哟,同時將“Api Compatibility Level”設(shè)置為.NET?Standard 2.0心墅。

3、創(chuàng)建ILRuntime的AppDomain

ILRuntime的AppDomain是一個獨立的運行環(huán)境榨乎,它可以加載和運行IL代碼怎燥。在Unity項目中摹迷,需要在啟動時創(chuàng)建一個ILRuntime的AppDomain缸榛,并將IL代碼加載到AppDomain中络拌。這可以通過在Unity項目中創(chuàng)建一個啟動腳本來實現(xiàn)懈费。在啟動腳本中秸架,需要使用ILRuntime的API加載和運行IL代碼阔籽,例如:

using ILRuntime.Runtime.Enviorment;

public class Startup : MonoBehaviour

{

? ? private AppDomain appDomain;

? ? private void Start()

? ? {

? ? ? ? appDomain = new AppDomain();

? ? ? ? appDomain.LoadAssembly("Assembly-CSharp");

? ? ? ? appDomain.Invoke("Assembly-CSharp.Main", "Start", null);

? ? }

? ? private void Update()

? ? {

? ? ? ? appDomain.Invoke("Assembly-CSharp.Main", "Update", null);

? ? }

}

在上面的代碼中甫贯,創(chuàng)建了一個ILRuntime的AppDomain涛漂,并將“Assembly-CSharp”程序集加載到AppDomain中篇梭。然后在Start和Update方法中氢橙,通過AppDomain的Invoke方法調(diào)用“Assembly-CSharp.Main”類的“Start”和“Update”方法。

三恬偷、Unity與ILRuntime的交互

Unity與ILRuntime之間的交互主要通過以下幾種方式實現(xiàn):

1悍手、使用ILRuntime的API調(diào)用Unity的API

ILRuntime提供了一些API來調(diào)用Unity的API,例如:

using UnityEngine;

using ILRuntime.Runtime.Enviorment;

public class Main : MonoBehaviour

{

? ? private AppDomain appDomain;

? ? private void Start()

? ? {

? ? ? ? appDomain = new AppDomain();

? ? ? ? appDomain.LoadAssembly("Assembly-CSharp");

? ? ? ? appDomain.Invoke("Assembly-CSharp.Main", "Start", null);

? ? ? ? var go = appDomain.Instantiate("Assembly-CSharp.TestGameObject");

? ? ? ? var transform = go.GetComponent<Transform>();

? ? ? ? transform.position = new Vector3(1, 2, 3);

? ? }

? ? private void Update()

? ? {

? ? ? ? appDomain.Invoke("Assembly-CSharp.Main", "Update", null);

? ? }

}

在上面的代碼中袍患,使用ILRuntime的API創(chuàng)建了一個GameObject坦康,并獲取了它的Transform組件,然后設(shè)置了Transform的位置诡延。

2滞欠、使用Unity的API調(diào)用ILRuntime的API

Unity可以通過反射機(jī)制調(diào)用ILRuntime中的API,例如:

using UnityEngine;

using System.Reflection;

using ILRuntime.Runtime.Enviorment;

public class Main : MonoBehaviour

{

? ? private AppDomain appDomain;

? ? private void Start()

? ? {

? ? ? ? appDomain = new AppDomain();

? ? ? ? appDomain.LoadAssembly("Assembly-CSharp");

? ? ? ? appDomain.Invoke("Assembly-CSharp.Main", "Start", null);

? ? ? ? var type = appDomain.LoadedTypes["Assembly-CSharp.TestClass"];

? ? ? ? var method = type.GetMethod("TestMethod");

? ? ? ? method.Invoke(null, null);

? ? }

? ? private void Update()

? ? {

? ? ? ? appDomain.Invoke("Assembly-CSharp.Main", "Update", null);

? ? }

}

在上面的代碼中肆良,使用Unity的反射機(jī)制獲取了ILRuntime中的“Assembly-CSharp.TestClass”類型和“TestMethod”方法筛璧,并調(diào)用了它。

3惹恃、使用委托實現(xiàn)Unity和ILRuntime的互相調(diào)用

ILRuntime提供了一個DelegateBridge類夭谤,它可以將Unity和ILRuntime中的委托類型互相轉(zhuǎn)換。例如:

using UnityEngine;

using System;

using ILRuntime.Runtime.Enviorment;

public class Main : MonoBehaviour

{

? ? private AppDomain appDomain;

? ? private void Start()

? ? {

? ? ? ? appDomain = new AppDomain();

? ? ? ? appDomain.LoadAssembly("Assembly-CSharp");

? ? ? ? appDomain.Invoke("Assembly-CSharp.Main", "Start", null);

? ? ? ? var type = appDomain.LoadedTypes["Assembly-CSharp.TestClass"];

? ? ? ? var method = type.GetMethod("TestMethod");

? ? ? ? var action = DelegateBridge.CreateDelegate(typeof(Action), method) as Action;

? ? ? ? action();

? ? }

? ? private void Update()

? ? {

? ? ? ? appDomain.Invoke("Assembly-CSharp.Main", "Update", null);

? ? }

}

在上面的代碼中巫糙,使用DelegateBridge類將ILRuntime中的“Assembly-CSharp.TestClass.TestMethod”方法轉(zhuǎn)換為Unity的Action委托類型朗儒,并調(diào)用了它。

四、ILRuntime的熱更新

ILRuntime的熱更新是指在運行時替換IL代碼采蚀,從而實現(xiàn)應(yīng)用程序的更新疲牵。ILRuntime的熱更新主要包括以下幾個步驟:

1、在ILRuntime的AppDomain中替換IL代碼

ILRuntime的AppDomain可以在運行時加載和卸載IL代碼榆鼠,因此可以在運行時替換IL代碼纲爸。例如:

using UnityEngine;

using ILRuntime.Runtime.Enviorment;

public class Main : MonoBehaviour

{

? ? private AppDomain appDomain;

? ? private void Start()

? ? {

? ? ? ? appDomain = new AppDomain();

? ? ? ? appDomain.LoadAssembly("Assembly-CSharp");

? ? ? ? appDomain.Invoke("Assembly-CSharp.Main", "Start", null);

? ? }

? ? private void Update()

? ? {

? ? ? ? appDomain.Invoke("Assembly-CSharp.Main", "Update", null);

? ? ? ? // 熱更新

? ? ? ? var newIL = File.ReadAllBytes("Assembly-CSharp.dll");

? ? ? ? appDomain.LoadAssembly(newIL);

? ? ? ? appDomain.Invoke("Assembly-CSharp.Main", "OnHotUpdate", null);

? ? }

}

在上面的代碼中,使用ILRuntime的API加載了“Assembly-CSharp”程序集妆够,并在Update方法中熱更新了IL代碼识啦。

2、使用Unity的AssetBundle實現(xiàn)熱更新

ILRuntime的熱更新也可以使用Unity的AssetBundle來實現(xiàn)神妹,這可以通過將IL代碼打包為AssetBundle颓哮,并在運行時下載和加載AssetBundle來實現(xiàn)。例如:

using UnityEngine;

using System.Collections;

using ILRuntime.Runtime.Enviorment;

public class Main : MonoBehaviour

{

? ? private AppDomain appDomain;

? ? private void Start()

? ? {

? ? ? ? StartCoroutine(DownloadAndLoadAssetBundle());

? ? }

? ? private void Update()

? ? {

? ? ? ? appDomain.Invoke("Assembly-CSharp.Main", "Update", null);

? ? }

? ? private IEnumerator DownloadAndLoadAssetBundle()

? ? {

? ? ? ? var request = UnityWebRequestAssetBundle.GetAssetBundle("http://localhost/Assembly-CSharp.assetbundle");

? ? ? ? yield return request.SendWebRequest();

? ? ? ? var assetBundle = DownloadHandlerAssetBundle.GetContent(request);

? ? ? ? var il = assetBundle.LoadAsset<TextAsset>("Assembly-CSharp.dll");

? ? ? ? appDomain = new AppDomain();

? ? ? ? appDomain.LoadAssembly(il.bytes);

? ? ? ? appDomain.Invoke("Assembly-CSharp.Main", "Start", null);

? ? }

}

在上面的代碼中鸵荠,使用Unity的WebRequest下載了“Assembly-CSharp.assetbundle”文件冕茅,并使用AssetBundle加載了“Assembly-CSharp.dll”文件,并將IL代碼加載到ILRuntime的AppDomain中蛹找。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末姨伤,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子庸疾,更是在濱河造成了極大的恐慌乍楚,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件届慈,死亡現(xiàn)場離奇詭異徒溪,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)金顿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門臊泌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人揍拆,你說我怎么就攤上這事渠概。” “怎么了礁凡?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵高氮,是天一觀的道長慧妄。 經(jīng)常有香客問我顷牌,道長,這世上最難降的妖魔是什么塞淹? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任窟蓝,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘运挫。我一直安慰自己状共,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布谁帕。 她就那樣靜靜地躺著峡继,像睡著了一般。 火紅的嫁衣襯著肌膚如雪匈挖。 梳的紋絲不亂的頭發(fā)上碾牌,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機(jī)與錄音儡循,去河邊找鬼舶吗。 笑死,一個胖子當(dāng)著我的面吹牛择膝,可吹牛的內(nèi)容都是我干的誓琼。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼肴捉,長吁一口氣:“原來是場噩夢啊……” “哼腹侣!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起每庆,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤筐带,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后缤灵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體伦籍,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年腮出,在試婚紗的時候發(fā)現(xiàn)自己被綠了帖鸦。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡胚嘲,死狀恐怖作儿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情馋劈,我是刑警寧澤攻锰,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站妓雾,受9級特大地震影響娶吞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜械姻,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一妒蛇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦绣夺、人聲如沸吏奸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽奋蔚。三九已至,卻和暖如春烈钞,著一層夾襖步出監(jiān)牢的瞬間旺拉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工棵磷, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留蛾狗,地道東北人。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓仪媒,卻偏偏與公主長得像沉桌,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子算吩,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 對C#熱更新方案ILRuntime的探究 轉(zhuǎn)載請標(biāo)明出處:http://www.cnblogs.com/zblad...
    拉夫斯基丶閱讀 1,557評論 0 1
  • 這個是我收集的Unity面試題留凭,為了應(yīng)對面試,同時幫助大家更好地復(fù)習(xí)Unity知識點偎巢,如果大家發(fā)現(xiàn)有什么錯誤蔼夜,(包...
    BiLi_Unity閱讀 2,875評論 1 5
  • 轉(zhuǎn)自:https://blog.csdn.net/dingxiaowei2013/article/details/...
    豆錚閱讀 1,259評論 0 2
  • 一:什么是協(xié)同程序? 在主線程運行的同時開啟另一段邏輯處理压昼,來協(xié)助當(dāng)前程序的執(zhí)行求冷,協(xié)程很像多線程,但是不是多線程窍霞,...
    胤醚貔貅閱讀 2,080評論 0 13
  • [Unity]技術(shù)學(xué)習(xí)路線圖(長期更新) Unity技術(shù)面試題 一:什么是協(xié)同程序匠题?答:在主線程運行時同時開啟另一...
    肖浩唄閱讀 23,436評論 15 243