Unity3D熱更新技術(shù)點——ToLua(上)

熱更新

在介紹tolua前衅胀,我們首先來了解一下在游戲開發(fā)中骄恶,熱更新的概念琉苇。

熱更新是一種手游及App常用的更新方式,舉例來說娇钱,游戲上線后伤柄,玩家需要通過應用商店及其他渠道下載第一個版本。在運營的過程中文搂,如游戲需要更換UI适刀、修改邏輯、開放功能等煤蹭,此時若不使用熱更新技術(shù)笔喉,就需要重新打包,那么玩家也就需要通過應用商店或其他渠道重新下載游戲硝皂。 熱更新可以在不重新下載客戶端的情況下常挚,更新游戲的內(nèi)容。

image

<figcaption style="margin-top: calc(0.666667em); padding: 0px 1em; font-size: 0.9em; line-height: 1.5; text-align: center; color: rgb(153, 153, 153);">目前手游這部分做得普遍比較成熟吧彪,大大小小的內(nèi)容升級基本都通過熱更新來完成</figcaption>

然而c#是一門編譯型語言待侵,其運行之前需要進行編譯丢早,而編譯的過程在移動平臺無法完成姨裸,所以當我們游戲的邏輯更改,代碼發(fā)生變化時怨酝,我們就需要重新在開發(fā)環(huán)境下編譯傀缩,然后重新打包,讓玩家下載最新版本农猬。這個過程中赡艰,會下載很多不需要更新的資源,便會增加玩家的時間及流量消耗斤葱,造成不好的用戶體驗慷垮。因此在移動平臺中便就出現(xiàn)了熱更新技術(shù)揖闸。

  • 在unity中,主要的熱更新方式有如下三種:

1.使用Lua編寫游戲邏輯料身;
Lua是一個小巧的腳本語言汤纸,由標準C編寫而成,幾乎在所有操作系統(tǒng)和平臺上都可以編譯芹血,運行贮泞。
使用lua熱更新就是在Unity環(huán)境里內(nèi)嵌一個lua虛擬機,經(jīng)常變動的和對執(zhí)行效率沒要求的邏輯用Lua實現(xiàn)幔烛,游戲啟動時加載服務器上最新的lua字節(jié)碼來執(zhí)行游戲啃擦。lua代碼都是運行時才編譯的,不運行的時候就如同一張圖片饿悬、一段音頻一樣令蛉,都是文件資源;所以更新邏輯只需要更新腳本狡恬,不需要再編譯言询,因而lua能輕松實現(xiàn)“熱更新”。
其實諸如python傲宜,javascript等腳本語言的話运杭,都是可以實現(xiàn)這個功能的。只不是目前幾個開源的函卒、成熟的熱更新方案都是基于lua的辆憔。

2.C#Light
C#Light是一個簡單的嵌入式腳本,模仿c#的語法風格报嵌,完全由pure c#寫成

3.C#反射技術(shù)
可以將部分邏輯提取至一個單獨的代碼庫工程中虱咧,打包為DLL,將DLL打包為AssetBundle锚国,Unity程序動態(tài)加載AssetBundle中的DLL文件腕巡,使用反射機制來調(diào)用代碼。用C#反射加載程序集的方式可以動態(tài)的從assetBundle資源包或其他資源包里加載腳本到工程中血筑。但因為蘋果官方禁止iOS下的程序熱更新绘沉,JIT在iOS下無效,所以這種方式無法在ios使用

本文中主要來了解第一種方式豺总,在unity的lua熱更新中车伞,有ulua、slua喻喳、xlua另玖、tolua等多種熱更新方案,這些方案提供了C#與Lua的互相調(diào)用機制。在本文我們以現(xiàn)今市面最常見的tolua為例谦去,通過一個小項目給讀者介紹tolua在unity中的使用方法慷丽。

注:本文中僅介紹tolua的用法,不會詳細介紹tolua熱更新的方法鳄哭,如需要了解tolua熱更新可以通過toluaLuaFramework框架作者的博客LuaFramework基礎來了解盈魁、學習。


ToLua使用

Tolua是Unity靜態(tài)綁定lua的一個解決方案窃诉,它通過C#中集成lua的插件杨耙,可以自動生成用于在lua中訪問Unity的綁定代碼,并把C#中的常量飘痛、變量珊膜、函數(shù)、屬性宣脉、類以及枚舉暴露給lua车柠。其從cstolua衍變而來。

既然要了解Tolua塑猖,第一步肯定是先從Tolua作者的GitHub下載Tolua資源GitHub - topameng/tolua: The fastest unity lua binding solution 同時我們可以通過其GitHub來了解Tolua的主要特性竹祷,也可以加tolua技術(shù)交流群進行討論及學習(在GitHub中有群號)。

下載完成后可以看到tolua文件夾中的目錄結(jié)構(gòu)羊苟,如下圖:

image

我們只需要將「Assets」塑陵、「Unity5.x」、「Luajit64」蜡励、「Luajit」四個文件夾復制到我們的工程文件夾中令花。 加載完成后,Unity中會出現(xiàn)如下提示框凉倚,我們點擊確定

image

然后在unity中就可以看到Tolua的主要文件列表

image

ToLua案例

在了解了基本的熱更新概念兼都,及ToLua資源的加載后,我們通過一個小的案例稽寒,來初步的掌握ToLua在Unity中的使用方法扮碧。 在本文中,我們使用ToLua來制作一個可以用按鍵控制滾動的小球杏糙,如下圖所示:

image

學習或使用過Unity的讀者應該能夠非常輕松的使用C#寫出這個小游戲慎王,那么我們現(xiàn)在來看使用ToLua是如何達到上圖效果的。

我們直接來看代碼搔啊,下面會對代碼進行逐行解釋:

Control.lua

Control = {}
local this = Control
require('Music')
local GameObject = UnityEngine.GameObject
local Input = UnityEngine.Input
local AudioSource = UnityEngine.AudioSource
local Rigidbody = UnityEngine.Rigidbody
local Color = UnityEngine.Color
local Sphere
local rigi
local force

function this.Start()
    Sphere = GameObject.Find('Sphere')
    Sphere : GetComponent('Renderer').material.color = Color(1, 0.1, 1)
    Sphere : AddComponent(typeof(AudioSource))
    coroutine.start(Music.PlaySound)
    Sphere : AddComponent(typeof(Rigidbody))
    rigi = Sphere : GetComponent('Rigidbody')
    force = 5
end

function this.Update()
    local h = Input.GetAxis('Horizontal')
    local v = Input.GetAxis('Vertical')
    rigi : AddForce(Vector3(h, 0, v) * force)
end 

Music.lua

--協(xié)程下載
--這里使用Tolua中提供的coroutine.www
Music = {}
local this = Music
function this.PlaySound()
    local audio = UnityEngine.GameObject.Find('Sphere') : GetComponent('AudioSource')
    local url = UnityEngine.WWW('https://etnly.oss-cn-shanghai.aliyuncs.com/%E5%B2%A1%E9%83%A8%E5%95%93%E4%B8%80%20-%20%E9%81%BA%E3%82%B5%E3%83%AC%E3%82%BF%E5%A0%B4%E6%89%80%EF%BC%8F%E6%96%9C%E5%85%89.ogg')
    coroutine.www(url)
    audio.clip = url : GetAudioClip()
    audio : Play()
end
  • 首先柬祠,我們在project面板中創(chuàng)建Script文件夾,下一層創(chuàng)建Lua文件夾负芋,這個文件夾會存放我們所有的lua腳本。

  • 然后我們來詳細解釋上方的代碼:

  1. Control = {} : 在lua中沒有類的概念,第一行中我們用lua表模擬一個類旧蛾,類名為Control莽龟;

  2. local this = Control : 既然在lua中不存在類的概念,那也不會存在this的用法锨天,這里同樣的毯盈,我們模擬一個this,讓this = Control類病袄;

  3. require('Music’) : lua通過require函數(shù)來加載模塊(希望讀者可以自行了解lua中模塊的含義)在本行中Muisc模塊是一個下載并播放音樂的協(xié)程模塊搂赋,具體代碼在Muisc.lua中;

  4. local GameObject = UnityEngine.GameObject : 這里及其以下四行都是對Unity中的類益缠、方法進行加載或者說調(diào)用脑奠,我們可以直接在代碼中使用UnityEngine.GameObject,或把UnityEngine.GameObject賦給一個變量(如第一行中幅慌,lua使用表來模擬類宋欺,那這里的GameObject也就是一個table類型);

  5. local Sphere : 這里及以下兩行胰伍,我們定義了幾個變量齿诞;

  6. function this.Start() end :這是lua中的函數(shù),this的含義在之前有提到骂租,我們也可以寫成Control.Start()祷杈, 我們在start函數(shù)中進行一些必要的初始化操作,可以把它看成Unity中的start(我們也可以給它起別的名字渗饮,這個函數(shù)的名字和之后我們在Unity中的調(diào)用沒有必然聯(lián)系)吠式,不要忘了加后面的end,這句話代表此方法的結(jié)尾抽米;

  7. Sphere = GameObject.Find('Sphere') : 我們通過GameObject.Find來找到Unity中的小球(需要注意特占,lua腳本無法綁定在Unity中的物體上,所以也無法直接在Unity的面板中綁定Unity中的對象云茸,我們只有通過查找的方式來找到Unity中的物體)是目;

  8. Sphere : GetComponent('Renderer').material.color = Color(1, 0.1, 1) :這一行中,我們使用GetComponent通過獲取Renderer組件标捺,改變小球的顏色 懊纳;

  9. Sphere : AddComponent(typeof(AudioSource)) : 使用AddComponent,給小球添加AudioSource組件亡容;

  10. coroutine.start(Music.PlaySound) : 開啟協(xié)程嗤疯, 我們可以直接看到 Music.lua這個腳本,在腳本中闺兢,我們使用ToLua封裝的coroutine.www()方法茂缚,來下載音樂,并通過之后的代碼來播放音樂;

  11. Sphere : AddComponent(typeof(Rigidbody)) : 給小球添加剛體 脚囊;

  12. rigi = Sphere : GetComponent('Rigidbody') : 獲取小球的剛體龟糕,將其賦給rigi ;

  13. force = 5 : 這里作為力的大谢谠拧讲岁;

  14. function this.Update() end : 與之前start函數(shù)類似,我們可以將其看作是Unity中的Update(再次聲明衬以,此處Lua函數(shù)名和Unity中的調(diào)用沒有必然聯(lián)系)缓艳;

  15. local h = Input.GetAxis('Horizontal') : 這一行及下一行,就是獲取按下相應按鍵看峻,相應軸上的位移量 阶淘;

  16. rigi : AddForce(Vector3(h, 0, v) * force) : 通過剛體的AddForce方法,給小球施加力备籽;

這就是我們整個例子的Tolua腳本使用說明舶治,那么我們該如何在Unity中來調(diào)用這些腳本呢。 下面我們來了解在C#中調(diào)用ToLua的方法车猬,代碼如下所示:

using UnityEngine;
using LuaInterface;
public class Control : MonoBehaviour {
    LuaState lua = null;
    LuaFunction luaFunc = null;
    void Start () {
        new LuaResLoader();
        lua = new LuaState();
        lua.Start();
        LuaBinder.Bind(lua);
        string luaPath = Application.dataPath + "/Scripts/Lua";//注意這里的文件位置
        lua.AddSearchPath(luaPath);
        lua.DoFile("Control.lua");
        CallFunc("Control.Start", gameObject);//調(diào)用lua中的this.Start函數(shù)
    }
    void Update () {
        CallFunc("Control.Update", gameObject);////調(diào)用lua中的this.Update函數(shù)
    }
    private void OnApplicationQuit()
    {
        lua.Dispose();
        lua = null;
    }
    void CallFunc(string func, GameObject obj){
        luaFunc = lua.GetFunction(func);
        luaFunc.Call(obj);
        luaFunc.Dispose();
        luaFunc = null;
    }
}

我們可以通過這段代碼來了解一些C#中調(diào)用Tolua的基本操作:

1.new LuaState() : 初始化Lua虛擬機
2.LuaState.Start() :開啟Lua虛擬機
3.LuaState.AddSearchPath(fullPath):添加目錄地址
4.LuaBinder.Bin(LuaState):向Lua虛擬機注冊Wrap類
5.new LuaResLoader() :自定義加載器加載lua文件
6.LuaState.DoFile()霉猛、LuaState.Require():加載Lua文件/模塊
7.LuaState.GetFunction:獲取Lua方法
8.LuaState.GetFunction.Call():調(diào)用Lua函數(shù)
9.Luafunction.Dispose(),LuaState.Dispose():釋放內(nèi)存

轉(zhuǎn)載于:https://zhuanlan.zhihu.com/p/42472089

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市珠闰,隨后出現(xiàn)的幾起案子惜浅,更是在濱河造成了極大的恐慌,老刑警劉巖伏嗜,帶你破解...
    沈念sama閱讀 211,561評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件坛悉,死亡現(xiàn)場離奇詭異,居然都是意外死亡承绸,警方通過查閱死者的電腦和手機裸影,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來军熏,“玉大人轩猩,你說我怎么就攤上這事〉磁欤” “怎么了均践?”我有些...
    開封第一講書人閱讀 157,162評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長摩幔。 經(jīng)常有香客問我彤委,道長,這世上最難降的妖魔是什么或衡? 我笑而不...
    開封第一講書人閱讀 56,470評論 1 283
  • 正文 為了忘掉前任焦影,我火速辦了婚禮车遂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘偷办。我一直安慰自己艰额,他們只是感情好澄港,可當我...
    茶點故事閱讀 65,550評論 6 385
  • 文/花漫 我一把揭開白布椒涯。 她就那樣靜靜地躺著,像睡著了一般回梧。 火紅的嫁衣襯著肌膚如雪废岂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,806評論 1 290
  • 那天狱意,我揣著相機與錄音湖苞,去河邊找鬼。 笑死详囤,一個胖子當著我的面吹牛财骨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播藏姐,決...
    沈念sama閱讀 38,951評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼隆箩,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了羔杨?” 一聲冷哼從身側(cè)響起捌臊,我...
    開封第一講書人閱讀 37,712評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎兜材,沒想到半個月后理澎,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,166評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡曙寡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,510評論 2 327
  • 正文 我和宋清朗相戀三年糠爬,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片举庶。...
    茶點故事閱讀 38,643評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡执隧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出灯变,到底是詐尸還是另有隱情殴玛,我是刑警寧澤,帶...
    沈念sama閱讀 34,306評論 4 330
  • 正文 年R本政府宣布添祸,位于F島的核電站滚粟,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏刃泌。R本人自食惡果不足惜凡壤,卻給世界環(huán)境...
    茶點故事閱讀 39,930評論 3 313
  • 文/蒙蒙 一署尤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧亚侠,春花似錦曹体、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至滞谢,卻和暖如春串稀,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背狮杨。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評論 1 266
  • 我被黑心中介騙來泰國打工母截, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人橄教。 一個月前我還...
    沈念sama閱讀 46,351評論 2 360
  • 正文 我出身青樓清寇,卻偏偏與公主長得像,于是被迫代替她去往敵國和親护蝶。 傳聞我的和親對象是個殘疾皇子华烟,可洞房花燭夜當晚...
    茶點故事閱讀 43,509評論 2 348

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

  • 何謂熱更新 熱更新搅方,每個程序員一聽就明白比吭,但是它語出何處,究竟表達了什么含義姨涡,到底代表了什么衩藤,對技術(shù)有什么要求,對...
    一杯毒酒閱讀 1,105評論 0 2
  • 何謂熱更新 Unity3D熱更新就是指:用戶重啟客戶端就能實現(xiàn)客戶端資源代碼更新的需求或者功能涛漂。 為何熱更新 熱更...
    京野男爵閱讀 1,544評論 0 6
  • 我是黑夜里大雨紛飛的人啊 1 “又到一年六月赏表,有人笑有人哭,有人歡樂有人憂愁匈仗,有人驚喜有人失落瓢剿,有的覺得收獲滿滿有...
    陌忘宇閱讀 8,529評論 28 53
  • 人工智能是什么?什么是人工智能悠轩?人工智能是未來發(fā)展的必然趨勢嗎间狂?以后人工智能技術(shù)真的能達到電影里機器人的智能水平嗎...
    ZLLZ閱讀 3,766評論 0 5
  • 首先介紹下自己的背景: 我11年左右入市到現(xiàn)在鉴象,也差不多有4年時間忙菠,看過一些關(guān)于股票投資的書籍,對于巴菲特等股神的...
    瞎投資閱讀 5,701評論 3 8