一、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
2.PanelManager:默认lua创建的panel都要在tag为GuiCamera的物体下,提供创建panel的方法
3.ThreadManager:解包与下载资源
lua代码分析:
PromptPanel.lua
1.函数是可以存储在变量中的。函数与其他所有值都是匿名的,即它们都没有名称。当讨论一个函数名时,实际上是在讨论一个持有某函数的变量。
a = {p = print} a.p("hello woeld") --hello woeld print = math.sin a.p(print(3.14159)) --约等于0 sin = a.p sin(10,20) --10 20所以对于:function foo(x) return 2*x end 其实就是等于:foo = function (x) return 2*x end
2.引用table
a = {} --创建一个table,并将它的引用存储到a a["x"] = 10 b = a --b与a引用了同一个table print(b["x"]) --10 b["x"] = 20 print(a["x"]) --20 a = nil --现在只有b还在引用table b = nil --再也没有对table的引用了
a = {} x = "y" a[x] = 10 print(a[x]) --10 print(a.x) --nil print(a.y) --10 --a.x等同于a["x"]那么,对于上面的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的方法,获取控件引用,进行逻辑处理。