国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

從游戲腳本語(yǔ)言說(shuō)起,剖析Mono所搭建的腳本基礎(chǔ)

2019-11-17 02:19:49
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

游戲腳本語(yǔ)言說(shuō)起,剖析Mono所搭建的腳本基礎(chǔ)

0x00 前言

在日常的工作中,我偶爾能遇到這樣的問(wèn)題:“為何游戲腳本在現(xiàn)在的游戲開(kāi)發(fā)中變得不可或缺?”。那么這周我就寫(xiě)篇文章從游戲腳本聊起,分析一下游戲腳本因何出現(xiàn),而mono又能提供怎樣的腳本基礎(chǔ)。最后會(huì)通過(guò)模擬Unity3D游戲引擎中的腳本功能,將Mono運(yùn)行時(shí)嵌入到一個(gè)非托管(C/C++)程序中,實(shí)現(xiàn)腳本語(yǔ)言和“引擎”之間的分離。

0x01 Why?從為何需要游戲腳本開(kāi)始

首先聊聊為何現(xiàn)在的游戲開(kāi)發(fā)需要使用游戲腳本這個(gè)話(huà)題。

為何需要有腳本系統(tǒng)呢?腳本系統(tǒng)又是因何而出現(xiàn)的呢?其實(shí)游戲腳本并非一個(gè)新的名詞或者技術(shù),早在暴雪的《魔獸世界》開(kāi)始火爆的年代,人們便熟知了一個(gè)叫做Lua的腳本語(yǔ)言。而當(dāng)時(shí)其實(shí)有很多網(wǎng)游都不約而同的使用了Lua作為腳本語(yǔ)言,比如網(wǎng)易的大話(huà)西游系列。但是在單機(jī)游戲流行的年代,我們卻很少聽(tīng)說(shuō)有什么單機(jī)游戲使用了腳本技術(shù)。這又是為什么呢?因?yàn)楫?dāng)時(shí)的硬件水平不高,所以需要使用C/C++這樣的語(yǔ)言來(lái)盡量壓榨硬件的性能,同時(shí),單機(jī)游戲的更新?lián)Q代并不如網(wǎng)游那么迅速,所以開(kāi)發(fā)時(shí)間、版本迭代速度并非其考慮的第一要素,因而可以使用C/C++這樣開(kāi)發(fā)效率不高的語(yǔ)言來(lái)開(kāi)發(fā)游戲。

但是隨著時(shí)間的推移,硬件水平逐年水漲船高,壓榨硬件性能的需求已經(jīng)不再迫切。相反,此時(shí)網(wǎng)游的興起卻對(duì)開(kāi)發(fā)速度、版本更迭提出了更高的要求。所以開(kāi)發(fā)效率并不高效,且投資巨大風(fēng)險(xiǎn)很高的C/C++便不再適應(yīng)市場(chǎng)的需求了。而更加現(xiàn)實(shí)的問(wèn)題是,隨著java、.net甚至是javascript等語(yǔ)言的流行,程序員可以選擇的語(yǔ)言越來(lái)越多,這更加導(dǎo)致了優(yōu)秀的C/C++程序員所占比例越來(lái)越小。而網(wǎng)游市場(chǎng)的不斷擴(kuò)大,這種對(duì)人才的需求也同樣越來(lái)越大,這就造成了大量的人才空缺,也就反過(guò)來(lái)提高了使用C/C++開(kāi)發(fā)游戲的成本。而由于C/C++是門(mén)入門(mén)容易進(jìn)階難的語(yǔ)言,其高級(jí)特性和高度靈活性帶來(lái)的高風(fēng)險(xiǎn)也是每個(gè)項(xiàng)目使用C/C++進(jìn)行開(kāi)發(fā)時(shí),所不得不考慮的問(wèn)題。

而一個(gè)可以解決這種困境的舉措便是在游戲中使用腳本。可以說(shuō)游戲腳本的出現(xiàn),不僅解決了由于C/C++難以精通而帶來(lái)的開(kāi)發(fā)效率問(wèn)題,而且還降低了使用C/C++進(jìn)行開(kāi)發(fā)的項(xiàng)目風(fēng)險(xiǎn)和成本。從此,腳本與游戲開(kāi)發(fā)相得益彰,互相促進(jìn),逐漸成為了游戲開(kāi)發(fā)中不可或缺的一個(gè)部分。

而到了如今手游興起的年代,市場(chǎng)的需求變得更加龐大且變化更加頻繁。這就更加要求需要有腳本語(yǔ)言來(lái)提高項(xiàng)目的開(kāi)發(fā)效率、降低項(xiàng)目的成本。而作為游戲腳本,它具體的優(yōu)勢(shì)都包括哪些呢?

  1. 易于學(xué)習(xí),代碼方便維護(hù)。適合快速開(kāi)發(fā)。
  2. 開(kāi)發(fā)成本低。由于上述第一點(diǎn),因?yàn)橐子趯W(xué)習(xí),所以可以啟用新人,同時(shí)開(kāi)發(fā)速度快,這些都是降低成本的方法。

因此,包括Unity3D在內(nèi)的眾多游戲引擎,都提供了腳本接口,讓開(kāi)發(fā)者在開(kāi)發(fā)項(xiàng)目時(shí)能夠擺脫C/C++(注:Unity3D本身是用C/C++寫(xiě)的)的束縛,這其實(shí)是變相的降低了游戲開(kāi)發(fā)的門(mén)檻,吸引了很多獨(dú)立開(kāi)發(fā)者和游戲制作愛(ài)好者。

0x02 What?Mono提供的腳本機(jī)制

首先一個(gè)問(wèn)題:Mono是什么?

Mono是一個(gè)由Xamarin公司所贊助的開(kāi)源項(xiàng)目。它基于通用語(yǔ)言架構(gòu)(Common Language Infrastructure ,縮寫(xiě)為CLI)和C#的ECMA 標(biāo)準(zhǔn)(Ecma-335、Ecam-334),提供了微軟的.Net框架的另一種實(shí)現(xiàn)。與微軟的.Net框架不同的是,Mono具備了跨平臺(tái)的能力,也就是說(shuō)它不僅能運(yùn)行在Windows系統(tǒng)上,而且還可以運(yùn)行在Mac OSX、linux甚至是一些游戲平臺(tái)上。

所以把它作為跨平臺(tái)的方案是像Unity3D這種開(kāi)發(fā)跨平臺(tái)游戲的游戲引擎的一個(gè)不錯(cuò)的選擇。但Mono又是如何提供這種腳本的功能的呢?

如果需要利用Mono為應(yīng)用開(kāi)發(fā)提供腳本功能,那么其中一個(gè)前提就是需要將Mono的運(yùn)行時(shí)嵌入到應(yīng)用中,因?yàn)橹挥羞@樣才有可能使得托管代碼和腳本能夠在原生應(yīng)用中使用。所以,我們可以發(fā)現(xiàn),將Mono運(yùn)行時(shí)嵌入應(yīng)用中是多么的重要。但在討論如何將Mono運(yùn)行時(shí)嵌入原生應(yīng)用中去之前,我們首先要搞清楚Mono是如何提供腳本功能的,以及Mono提供的到底是怎樣的腳本機(jī)制。

Mono和腳本

本小節(jié)將會(huì)討論如何利用Mono來(lái)提高我們的開(kāi)發(fā)效率以及拓展性而無(wú)需將已經(jīng)寫(xiě)好的C/C++代碼重新用C#寫(xiě)一遍,也就是Mono是如何提供腳本功能的。

常常使用一種編程語(yǔ)言開(kāi)發(fā)游戲是比較常見(jiàn)的一種情況。因而游戲開(kāi)發(fā)者往往需要在高效率的低級(jí)語(yǔ)言和低效率的高級(jí)語(yǔ)言之間抉擇。例如一個(gè)用C/C++開(kāi)發(fā)的應(yīng)用的結(jié)構(gòu)如下圖:

可以看到低級(jí)語(yǔ)言和硬件打交道的方式更加直接,所以其效率更高。

可以看到高級(jí)語(yǔ)言并沒(méi)有和硬件直接打交道,所以其效率較低。如果以速度作為衡量語(yǔ)言的標(biāo)準(zhǔn),那么語(yǔ)言從低級(jí)到高級(jí)的大體排名如下:

  • 匯編語(yǔ)言
  • C/C++,編譯型靜態(tài)不安全語(yǔ)言
  • C#、Java,編譯型靜態(tài)安全語(yǔ)言
  • Python, Perl, Javascript,解釋型動(dòng)態(tài)安全語(yǔ)言

開(kāi)發(fā)者在選擇適合自己的開(kāi)發(fā)語(yǔ)言時(shí),的確面臨著很多現(xiàn)實(shí)的問(wèn)題。

高級(jí)語(yǔ)言對(duì)開(kāi)發(fā)者而言效率更高,也更加容易掌握,但高級(jí)語(yǔ)言也并不具備低級(jí)語(yǔ)言的那種運(yùn)行速度、甚至對(duì)硬件的要求更高,這在某種程度上的確也決定了一個(gè)項(xiàng)目到底是成功還是失敗。

因此,如何平衡兩者,或者說(shuō)如何融合兩者的優(yōu)點(diǎn),便變得十分重要和迫切。腳本機(jī)制便在此時(shí)應(yīng)運(yùn)而生。游戲引擎由富有經(jīng)驗(yàn)的開(kāi)發(fā)人員使用C/C++開(kāi)發(fā),而一些具體項(xiàng)目中功能的實(shí)現(xiàn),例如UI、交互等等則使用高級(jí)語(yǔ)言開(kāi)發(fā)。

通過(guò)使用高級(jí)腳本語(yǔ)言,開(kāi)發(fā)者便融合了低級(jí)語(yǔ)言和高級(jí)語(yǔ)言的優(yōu)點(diǎn)。同時(shí)提高了開(kāi)發(fā)效率,如同第一節(jié)中所講的,引入腳本機(jī)制之后開(kāi)發(fā)效率提升了,可以快速的開(kāi)發(fā)原型,而不必把大量的時(shí)間浪費(fèi)在C/C++上。

腳本語(yǔ)言同時(shí)提供了安全的開(kāi)發(fā)沙盒模式,也就是說(shuō)開(kāi)發(fā)者無(wú)需擔(dān)心C/C++開(kāi)發(fā)的引擎中的具體實(shí)現(xiàn)細(xì)節(jié),也無(wú)需關(guān)注例如資源管理和內(nèi)存管理這些事情的細(xì)節(jié),這在很大程度上簡(jiǎn)化了應(yīng)用的開(kāi)發(fā)流程。

而Mono則提供了這種腳本機(jī)制實(shí)現(xiàn)的可能性。即允許開(kāi)發(fā)者使用JIT編譯的代碼作為腳本語(yǔ)言為他們的應(yīng)用提供拓展。

目前很多腳本語(yǔ)言的選擇趨向于解釋型語(yǔ)言,例如cocos2d-js使用的javascript。因此效率無(wú)法與原生代碼相比。而Mono則提供了一種將腳本語(yǔ)言通過(guò)JIT編譯為原生代碼的方式,提高了腳本語(yǔ)言的效率。例如,Mono提供了一個(gè)原生代碼生成器,使你的應(yīng)用的運(yùn)行效率盡可能高。同時(shí)提供了很多方便的調(diào)用原生代碼的接口。

而為一個(gè)應(yīng)用提供腳本機(jī)制時(shí),往往需要和低級(jí)語(yǔ)言交互。這便不得不提到將Mono的運(yùn)行時(shí)嵌入到應(yīng)用中的必要性了。那么接下來(lái),我將會(huì)討論一下如何將Mono運(yùn)行時(shí)嵌入到應(yīng)用中。

Mono運(yùn)行時(shí)的嵌入

既然我們明確了Mono運(yùn)行時(shí)嵌入應(yīng)用的重要性,那么如何將它嵌入應(yīng)用中就成為了下一個(gè)值得討論的話(huà)題。

這個(gè)小節(jié)我會(huì)為大家分析一下Mono運(yùn)行時(shí)究竟是如何被嵌入到應(yīng)用中的,以及如何在原生代碼中調(diào)用托管方法,相應(yīng)的,如何在托管代碼中調(diào)用原生方法。而眾所周知的一點(diǎn)是,Unity3D游戲引擎本身是用C/C++寫(xiě)成的,所以本節(jié)就以Unity3D游戲引擎為例,假設(shè)此時(shí)我們已經(jīng)有了一個(gè)用C/C++寫(xiě)好的應(yīng)用(Unity3D)。

將你的Mono運(yùn)行時(shí)嵌入到這個(gè)應(yīng)用之后,我們的應(yīng)用就獲取了一個(gè)完整的虛擬機(jī)運(yùn)行環(huán)境。而這一步需要將“libmono”和應(yīng)用鏈接,一旦鏈接完成,你的C++應(yīng)用的地址空間就會(huì)像下圖一般:

而在C/C++代碼中,我們需要將Mono運(yùn)行時(shí)初始化,一旦Mono運(yùn)行時(shí)初始化成功,那么下一步最重要的就是將CIL/.NET代碼加載進(jìn)來(lái)。加載之后的地址空間將會(huì)如下圖所示:

那些C/C++代碼,我們通常稱(chēng)之為非托管代碼,而通過(guò)CIL編譯器生成CIL代碼我們通常稱(chēng)之為托管代碼。所以,將Mono運(yùn)行時(shí)嵌入我們的應(yīng)用,可以分為三個(gè)步驟:

  1. 編譯C++程序和鏈接Mono運(yùn)行時(shí)
  2. 初始化Mono運(yùn)行時(shí)
  3. C/C++和C#/CIL的交互

讓我們一步一步的進(jìn)行。首先我們需要將C++程序進(jìn)行編譯并鏈接Mono運(yùn)行時(shí)。此時(shí)我們會(huì)用到pkg-config工具。在Mac上使用homebrew來(lái)進(jìn)行安裝,在終端中輸入命令“brew install pkgconfig”,可以看到終端會(huì)有如下的輸出內(nèi)容:

==> Downloading https://homebrew.bintray.com/bottles/pkg-config-0.28.mavericks.bottle.2.tar.gz######################################################################## 100.0%==> Pouring pkg-config-0.28.mavericks.bottle.2.tar.gz
發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 大理市| 儋州市| 崇信县| 浏阳市| 昌吉市| 蕉岭县| 中江县| 双城市| 渝北区| 威信县| 南投市| 绍兴县| 庄河市| 张北县| 洛浦县| 婺源县| 九台市| 河东区| 仪陇县| 惠州市| 通山县| 凤凰县| 梓潼县| 内乡县| 淮阳县| 崇礼县| 平泉县| 吉林省| 通辽市| 扎赉特旗| 嘉祥县| 同心县| 安宁市| 丰县| 安化县| 曲松县| 马尔康县| 江津市| 宣恩县| 保德县| 建德市|