一、tolua#
c#調用lua:LuaState[變量名/函數名]
1.LuaState
a.執行lua代碼段
DoString(string)
DoFile(.lua文件名)
Require(.lua文件名(但沒有.lua后綴))
b.獲取lua函數或者表
LuaFunction func = lua.GetFunction(函數名); 或者 LuaFunction func = lua[函數名] as LuaFunction;
LuaTable table = lua.GetTable(表名);
c.Start():如果需要使用wrap,則需要調用該方法
2.LuaFunction
Call()
3.LuaTable
LuaTable[變量名/函數名]
ToArray()
lua調用c#
在c#中將引用傳遞到lua中后:
1.通過“.” (點號)來使用非靜態的變量以及靜態的變量與方法
2.通過'':“ (冒號)來使用非靜態的方法
3.通過"{}"來傳遞數組給c#
4.創建GameObject:newObject(變量)
5.摧毀GameObject:destroy(變量)
6.獲取組件:GetComponent('LuaBehaviour')
二、LuaFramework(使用PureMVC)
a.基礎模塊
1.Util:對Mono的功能進行封裝,這樣不繼承Mono的類就能使用Mono的東西了(如transform.Find、GetComponent);還有其他的工具方法
2.AppFacade:繼承Facade,整套框架的入口
3.Base:繼承MonoBehaviour,是一切View和Manager的基類;持有各種Manager的引用;能注冊移除(view所感興趣的)信息
4.View:只有一個方法:public virtual void OnMessage(IMessage message) 這是處理信息的方法
5.Manager:繼承Base
6.AppView:繼承View,是一個范例:注冊View所感興趣的信息,處理信息
b.lua模塊
1.LuaFileUtils:通過.lua文件路徑和AssetBundle文件路徑這兩種方式來找.lua文件,並讀取返回byte[]
2.LuaLoader:繼承LuaFileUtils,並無重要變化
3.LuaEvent:類似c#中的event,提供Add和Remove方法
4.LuaLooper:繼承MonoBehaviour,在Update / LateUpdate / FixedUpdate中執行對應的LuaEvent
5.LuaBinder:如果執行的.lua文件需要用到unity中的類型,則需要用這個類給LuaState進行綁定
6.LuaManager:繼承Manager,入口類,初始化Lua代碼加載路徑(調試模式下是在Assets \ LuaFramework目錄下,非調試模式是在C:\luaframework\lua(window系統),默認是非調試模式),引用一個LuaState並封裝其功能(讀取lua文件、調用方法等)
7.LuaBehaviour:繼承View,在Awake / Start中調用lua中對應的方法;並提供點擊事件的相關處理
c.Manager模塊
1.ResourceManager:加載AssetBundle的相關操作。在pc平台上默認加載的是Assets\StreamingAssets里的東西,移動平台上則是Application.persistentDataPath。那么如果我們想在pc平台上像移動平台一樣讀取外部路徑(使用www),在pc平台模擬熱更新,那么就可以在Initialize這個方法修改:m_BaseDownloadingURL = "file:///" + Util.DataPath;
unity5加載AB包的四個步驟:
a.為assetbundle起名字,並打包
b.加載總的清單文件
c.加載assetbundle的依賴文件
d.加載assetbundle
m_Dependencies:key為AB包的名字,value為依賴的AB包的名字
m_LoadedAssetBundles:key為AB包的名字,value為加載后的AB包
m_LoadRequests:key為AB包的名字,value為對包內資源的請求
先通過Initialize方法加載總的清單文件,然后我們可以通過LoadPrefab方法來加載AB包,此時會把對這個AB包的請求放在m_LoadRequests中,然后在OnLoadAsset方法對該AB包的所有請求進行處理,通過GetLoadedAssetBundle方法看看內存中有沒有這個AB包,如果有的話,再檢查一下該AB包的依賴包是否也在內存中,如果都在,就把請求的包內資源加載出來,並回調方法。如果出現缺包情況,會通過OnLoadAssetBundle方法加載AB包及其依賴包(使用遞歸)。
至於卸載AB包,使用的是UnloadAssetBundle方法。這里還有說一下引用計數的問題,例如有A1A2A3三個包,A2A3依賴A1,然后我們加載A2A3。那么A1的引用計數為2,A2的引用計數為1,A3的引用計數為1,當使用UnloadAssetBundle卸載掉A2包時,A1的引用計數變為1,此時還會留在內存中,再卸載A3包,A1的引用計數變為0,A1包就自動被卸載了。包被加載一次,則引用計數加1,所以上面的A2A3包引用計數為1,;包被依賴一次,則引用計數加1,所以上面的A1包引用計數為2,;每次卸載時計數減1,減到0則從內存中去掉。
2.PanelManager:默認lua創建的panel都要在tag為GuiCamera的物體下,提供創建panel的方法
3.ThreadManager:解包與下載資源
lua代碼分析:
PromptPanel.lua
1.函數是可以存儲在變量中的。函數與其他所有值都是匿名的,即它們都沒有名稱。當討論一個函數名時,實際上是在討論一個持有某函數的變量。
所以對於:function foo(x) return 2*x end 其實就是等於:foo = function (x) return 2*x end
那么對於:function PromptPanel.Awake(obj) xxx end 其實就是等於:PromptPanel.Awake = function (obj) xxx end
2.引用table
那么,對於上面的PromptPanel.Awake,就是等於PromptPanel["Awake"]
PromptCtrl.lua
1.對於沒有local聲明的變量均為全局變量,可以在其他.lua文件中調用
2.在Common/define.lua中注冊View、Controller,define.lua中持有各種manager的引用
PromptPanel & PromptCtrl:PromptPanel維護了面板的控件變量,提供給PromptCtrl使用,沒有model層是因為沒有數據
CtrlManager:管理controller層,維護所有的controller
Game:在OnInitOK方法中指定開始的panel,例如例子中的:local ctrl = CtrlManager.GetCtrl(CtrlNames.Prompt);
總結
1.對於一個panel,需要添加或修改的文件:
a.添加xxxPanel & xxxCtrl
b.修改define、Game、CtrlManager
詳細的可見:http://blog.csdn.net/adambieber/article/details/47402805
2.在lua中使用AB包內的資源的兩種方法:
a.panelMgr:CreatePanel('Prompt', this.OnCreate);
b.resMgr:LoadPrefab('prompt', { 'PromptItem' }, this.InitPanel);
其中a是對b的進一步封裝,因此兩者都需要提供AB包名、要訪問的包內資源名字(如果是panel,則默認資源名為AB包名+"Panel")以及回調方法(參數是AB包中的資源)
3.熱更新的四個步驟:打包、解包、更新和加載。而這四個步驟框架已經給我們封裝好了,基本上就不需要我們去管了,但還是很有必要理解其中的過程。
a.打包:將資源全部打包到StreamingAssets文件夾
打包類:LuaFramework / Editor / Packager
打包lua文件:HandleLuaBundle,對Assets\LuaFramework\Lua 與 Assets\LuaFramework\ToLua\Lua這兩個目錄下的所有lua文件進行打包
打包圖片等資源:HandleExampleBundle
b.解包:在移動端StreamingAssets這個文件夾是只讀的,但是要做熱跟新的話,就需要寫入文件,因此Application.persistentDataPath這個可讀可寫的路徑才是數據在移動端的存放路徑,同時也為了比較MD5的值,就需要將StreamingAssets的東西解包(復制)到Application.persistentDataPath
c.更新:files.txt這個文件記錄了所有的資源文件及其MD5值,每次進入游戲時都會從服務器下載最新的files.txt,然后對其遍歷比較MD5值,如果值不同或者不存在則下載
d.加載:先加載資源的依賴,再加載資源
那么,如果我們對外發布了一個版本1.1,然后更改資源,發布1.2,要做的就是:重新生成apk並上傳,然后將StreamingAssets文件夾下的東西上傳到服務器,具體位置見AppConst.WebUrl;對於用戶來說,如果他安裝的是1.1,那么就會下載更新,如果他安裝的是1.2,那么解包之后就得到最新的資源了,無需更新了。
4.整套框架的工作流程:
c#
打包好后,啟動游戲,GameManager會進行一些判斷,如果這是游戲安裝之后的第一次啟動,那么就會進行解包操作。如果AppConst.UpdateMode為false,那么就不會檢測更新,否則就會進行更新操作。然后進入初始化操作,調用Game.lua中的OnInitOK方法,進入lua邏輯。
lua
然后調用指定控制器的Awake方法、PanelManager的CreatePanel方法,調用c#代碼,創建panel,為其添加LuaBehaviour,調用xxxPanel.lua的方法,獲取控件引用,進行邏輯處理。
From:http://blog.csdn.net/lyh916/article/details/45021703
