美文网首页
LuaFramework

LuaFramework

作者: passiony | 来源:发表于2018-06-13 21:04 被阅读231次

    ULUA简介:

    Lua Framework

    ULUA:Unity AssetStore 中一款热更新插件Lua Framework 的简称,2015年发布v1.1版本并且停止了更新,但是由于国内手游这几年的飞速发展和对热更新的大量需求,LuaFramework由国内一个社群
    (http://www.ulua.org/index.html) 在继续进行维护。并且在原版基础上添加了cstolua去反射机制,大大的提上了ulua的效率,并且给我们提供了简单易学的框架demo。真的感谢这些大牛们。
    最新下载地址可以去社区群主的GitHub下载;
    LuaFramework_UGUI:(https://github.com/jarjin/LuaFramework_UGUI)
    LuaFramework_NGUI:(https://github.com/jarjin/LuaFramework_NGUI)

    ulua和slua框架的性能测试对比

    slua成绩:
    属性的读取和设置 cost time:0.27200000000001
    成员方法的调用 cost time:0.099999999999994
    静态方法调用 cost time: 0.179
    纯属性设置 cost time: 0.09899999999999
    构造valuetype i,i,i 20万次 cost time: 0.13799999999999
    构造valuetype i,i,i 200万次 cost time: 1.387
    构造valuetype 1,1,1 20万次 cost time: 0.131
    构造valuetype 1,1,1 200万次 cost time: 1.313

    cstolua成绩:
    属性的读取和设置20万次 cost time:0.17700000000002
    成员方法的调用20万次 cost time:0
    静态方法调用20万次 cost time: 0
    纯属性设置20万次 cost time: 0.08499999999998
    构造valuetype i,i,i 20万次 cost time: 0.027999999999963
    构造valuetype i,i,i 200万次 cost time: 0.26600000000002
    构造valuetype 1,1,1 20万次 cost time: 0
    构造valuetype 1,1,1 200万次 cost time: 0.0020000000000095

    ulua/cstolua全面领先slua,这才是真实数据!


    LuaFramework文件结构

    • Editor:生成_Wrap文件和Build xxxResource的编辑器工具。

    • Examples :框架自带的Demo例子,如果只需要框架的同学,里面的资源可以删除掉。
      Builds:里面是需要热更的Prefab资源。用于生成assetbundle而准备的资源。
      Editor:里面是例子用到的一个新手引导步骤演示的编辑器脚本。
      Editor Default Resource:目录是新手引导步骤对话框用的的图片资源。
      Textures:里面是Buidls目录里面图集的原图文件。

    • Lua:框架自带的Lua源码目录,用户自定义的Lua脚本也就是放在这里面,最后打包的时候,打包脚本会将其按目录结构生成到StreaminAssets目录里面去,然后在将其上传到游戏的Web服务器上面,用于准备被每个游戏客户端下载更新他们本地的Lua脚本。达到热更目的。
      3rd:里面是第三方的一些插件lua、实例源码文件,比如:cjson、pbc、pblua、sproto等。
      Common:公用的lua文件目录,如define.lua文件,一些变量声明,全局配置等,functions.lua常用函数库,通讯的protocal.lua协议文件。
      Controller:控制器目录,它不依赖于某一个Lua面板,它是独立存活在Luavm中的一个操作类,操作数据、控制面板显示而已。
      Logic:目录里面存放的是一些管理器类,比如GameManager游戏管理器、NetworkManager网络管理器,如果你有新的管理器可以放到里面。
      View:这是面板的视图层,里面都是一些被Unity调用的面板的变量,走的是Unity GameObject的生命周期的事件调用。

    • Plugins:ulua底层库所在的目录,里面存放的是不同平台的底层库,之所以ulua效率高,就是它是纯c的lua虚拟机,而不是c#解释型的。
      Andriod:安卓lua虚拟机底层库,里面分为armv7-a与Intel x86平台。
      iOS:里面就是苹果lua虚拟机底层库。
      ulua.bundle:里面是Mac机器的底层库。
      x86:里面是Win32/Linux32位机器的lua虚拟机底层库。
      x86_64:里面是Win64/Linux64位机器的lua虚拟机底层库。

    • Scripts:框架的C#脚本层,之所以这个目录跟lua目录都放在最外层,为了让用户一眼都能找到,明白是什么。
      Common:框架的公用定义类。BehaviourBase(行为基类)、GlobalGenerator全局构造器、与luavm通知unity游戏对象的“LuaBehaviour”桥类。
      ConstDefine:常量定义目录,AppConst(应用常量)ManagerName(管理器名称)NotiConst(通知常量,用于mvc消息通知)。
      Controller:控制器目录,分为Boostraps启动控制器,跟Command常用逻辑控制器。
      Framework:经过修改过的PureMVC的框架文件。
      Manager:Unity提供基础功能的管理器类,音乐、面板、线程、资源等众多管理器。
      Network:网络的常用辅助类,ByteBuffer字节操作封装类,网络协议类,转换器类。
      ObjectPool:对象池工具。
      Utility:常用工具类。
      View:C#用的PureMVC的视图层。

    • Scenes:框架自带demo的场景。

    • uLua:ulua/cstolua的核心目录,里面还有经过我们修缮后ulua的基础使用例子,用户初学者最佳。
      Core:顾名思义,ulua的核心目录,所有c#与lua的交互都是通过它进行调度的。
      Docs:ulua自带的文档目录,因为ulua基于LuaInterface,所以这里面就是它的文档。
      Editor:这是供cstolua去反射定义Wrap文件列表的工具类目录。
      Examples:经过我们修改增加后ulua自带的例子。
      Source:这个是cstolua的核心目录,里面有Base核心目录,与动态生成用于存放LuaWrap类的缓存目录。


    框架demo运行流程

    demo运行流程
    • 1.打开LuaFramework/Scenes下的main场景。

    • 2.找到GameManager游戏对象,身上运行着一个Main.cs脚本,通过
      AppFacade.Instance.StartUp() ,启动PureMVC框架。“框架”主要指以AppFacade为核心的一个消息分发控制体系。

    • 3.在StartUp方法中发送了一个命令给Model层的StartUpCommand,在GameManager游戏对象身上有添加了N多个管理器,供C#和Lua层去调用,包括LuaManager(Lua管理器),NetworkManager(网络管理器),PanelManager(页面管理器),ResourcesManager(资源管理器),SoundManager声音管理器,GameManager(热更新/游戏管理器)等管理器类。

    • 4.GameManager组件在运行后,进行了资源的热更新检测逻辑,并加载lua脚本。
      解压:根据需求,从streamingAssetsPath目录(游戏数据,可读)拷贝到persistentDataPath目录(游戏沙盒,可读可写)。
      更新:根据files.txt文件,从服务器WebUrl下载文件更新到persistentDataPath目录。
      加载lua:从persistentDataPath目录中加载lua脚本,并进入Game.lua的逻辑。

    • 5.GameManager在解压和更新完后,执行OnResourceInited,执行初始化资源管理器ResourceManager,加载AssetBundle的环境,因为所有的prefab资源和lua资源都在bundle中。

    • 6.GameManager加载完资源管理器后,加载OnInitialize方法,初始LuaManager,然后加载第一个lua的脚本Game.lua,和Network.lua,并且执行Game的初始化函数OnInitOK。

    • 7.Game.lua脚本执行OnInitOK函数,加载例子的messagePanel.lua和promptPanel.lua脚本,这两个UI界面,分别被拆分成两个脚本,一个Panel和一个Ctrl共同控制页面,实现了MVC的分层。

    • 8.创建页面使用PanelManager页面管理器,
      public void CreatePanel(string name, LuaFunction func = null)

    • 9.加载预制体使用ResourcesManager资源管理器,
      public void LoadPrefab(string abName, string[] assetNames, LuaFunction func)

    • 10.播放声音使用SoundManager声音管理器,
      public void PlayBacksound(string name, bool canPlay)

    • 11.点击button按钮发送网络事件,使用了NetworkManager网络管理器,
      public void SendMessage(ByteBuffer buffer)

    PureMVC框架

    PureMVC

    框架配置常量

    框架配置常量

    AppConst

    • 1.DebugMode
      对于LuaManager来说,如果值为true,那么lua代码的加载路径就为"LuaFramework/lua/"和"LuaFramework/Tolua/Lua/"这两个路径(也就是pc上的本地路径),否则为Util.DataPath + "lua"(也就是手机上的沙盒路径)

    • 2.ExampleMode
      如果AppConst.ExampleMode为true,那么就会对"Assets/LuaFramework/Examples/Builds/"这个路径下的素材进行打包,打包到StreamingAssets这个目录下。这里我建议不要修改这个值(保持为true),通过系列二的打包工具将素材的路径改了就可以了。

    • 3.UpdateMode
      如果为true,则会访问服务端进行下载更新

    • 4.LuaBundleMode
      如果AppConst.LuaBundleMode为true,那么就会对"LuaFramework/lua/"和"LuaFramework/Tolua/Lua/"这两个路径下的lua代码进行打包成 .Unity3D,打包到StreamingAssets/lua/这个目录下;否则,就是将这两个路径的文件复制到目标目录下。如果要导出apk,那么要将这个值改为true;如果只是在编辑器上测试,可以改为false。

    • 5.LuaEncode
      我们打开ulua/Editor/Packager.cs打包脚本。这里面根据不同的平台打包相应的资源。HandleExampleBundle函数就是将Examples/Builds下面的素材统一按照Unity的规则进行打包成assetbundle文件。 我们主要是看HandleLuaFile函数的操作流程。
      (1)在StreamingAssets目录下面新建lua目录,用于存放编码后的lua文件。
      (2)遍历Lua目录下面所有的lua文件,并且根据目录结构创建相应目录树。
      (3)如果AppConst.LuaEncode 设置了编码开关,就启动编码操作,否则直接复制源码过去。
      (4)然后将前面的图片素材assetbundle跟相对应的lua文件目录,统一遍历计算出MD5/CRC,生成到files.txt里面。

    ulua脚本的声明周期

    每一个panel页面默认都会被绑定一个LuaBehaviour脚本,用于直接调用panel同名的一个lua脚本,这样每个panel页面的lua脚本就会拥有Awake,Start,OnDestroy等相对应的生命周期。并且还可以通过LuaBehaviour帮助页面里面的按钮进行绑定按钮等的点击事件。

    function xxxPanel.Awake(go)
        this.gameObject=go;
        this.transform=go.transform;
        this.behavior=this.transform:GetComponent('LuaBehaviour');
        --Button绑定事件
        this.loginBtn = this.transform:Find("LoginBtn").gameObject;
        this.behavior:AddClick(this.loginBtn,this.OnClick);
    end
    function xxxPanel.OnClick()
        log('点击事件');
    end
    function xxxPanel.Start()
    end
    function xxxPanel.OnDestroy()
    end
    

    ulua的Update方法

    刚才我们说了LuaBehaviour可以给同名的lua脚本添加一个生命周期,但是不建议添加Update,因为大量的C#调用Lua脚本会造成性能瓶颈。出于效率的考虑,tolua提供了名为UpdateBeat的对象,在LuaFramework中,只需给UpdateBeat添加回调函数,该函数便会每帧执行,相当于Monobehaviour的Update方法。

    function xxxPanel.Start()
        --开启Lua的Update
        UpdateBeat:Add(this.Update)
    end
    --Update方式
    function xxxPanel.Update()
        this.image.transform:Rotate(Vector3.forward,20);
    end
    function xxxPanel.OnDestroy()
        UpdateBeat:Remove(this.Update);
    end
    

    ulua的协程方法

    lua语法本身有协程,但是我们希望在lua中使用像unity的协程,可以方便的延迟,下载等,于是tolua为我们提供了ulua协程。

    function xxxPanel.Start()
        --开启协程
        this.co = coroutine.start(this.test_coroutine);
    end
    function xxxPanel.test_coroutine() 
        coroutine.wait(1);--延迟一秒
        coroutine.step();--延迟一帧
        
        local www = WWW("http://bbs.ulua.org/readme.txt");
        coroutine.www(www);
        logWarn(www.text);      
    end
    function xxxPanel.OnDestroy()
         --销毁协程
        coroutine.stop(this.co);
    end
    

    Ulua&ToLua 调试

    相关文章

      网友评论

          本文标题:LuaFramework

          本文链接:https://www.haomeiwen.com/subject/mdyseftx.html