zoukankan      html  css  js  c++  java
  • 热更新之lua框架设计

           目前中大型游戏项目包含部分VR与AR项目,都需要热更新与在线修改Bug等功能实现,虽然Xlua等插件已经给出了关于C#与Lua语言之间的双向无缝调用实现,但是就热更新的架构却没有提出,这需要广大游戏公司的开发人员自己来设计一套lua框架。
          早期热更新的概念与实现机理刚传入国内实现的时候,很多公司采用纯lua脚本的方式,来构建整个项目。 这种方式开发速度慢,且极易出错,开发效率不高。所以后来各公司就纯lua的热更新技术,自己来进行架构设计,引入例如MVC的分层理念,然后通过C#与lua之间的映射方式,来让lua文件获取unity的生命周期函数,以此来获得更高的开发效率。
          笔者认为最好的方式应该把业务功能相对稳定的功能用C#来开发,而lua框架部分也仅仅处理游戏项目中业务需求随事件频繁更新的业务需求,例如游戏中的“每日公告”,“每日任务”等。以上问题比较复杂,笔者本篇文章,就纯lua语言来开发一套简单的lua框架系统,实现以上描述的业务功能实现。
         首先为了避免直接深入代码的海洋,先就笔者设计的框架给出一个整体设计图,供参考。

    以上架构图从LuaStartGame这个C#脚本入口开始,然后后续业务基本采用lua语言编写。LuaStartGame.cs 脚本如下。
    namespace LuaFramework{
        public class LuaGameStart : MonoBehaviour{
            void Start()
            {
                LuaHelper.GetInstance().DoString("require 'StartGame'");
            }
        }//Class_end
    }//namespace_end

        以上项目中的LuaHelper封装了Xlua的环境上下文(LuaEnv)、自定义lua文件的存取路径(不再使用xlua默认的Resources)以及常用lua方法等。
       StartGame.lua 脚本基本没有太多业务,主要起到承上启下,便于日后扩充的中间“过渡”脚本使用,代码如下:

    ---
    ---  Lua项目开始入门脚本
    ---
    --引入项目常量与“枚举”
    require("SysDefine")
    --引入项目初始化核心脚本
    require("ProjectInit")

    --项目开始
    ProjectInit.Init()

           以上脚本SysDefine中以“表”(Table)的形式定义了项目中可能用到的所有“控制层”与“显示层”的lua脚本,以方便在后续lua脚本中使用,这个机制类似于C#中使用一个类来集中定义项目中所有的常量与枚举等类型。
          ProjectInit.lua 是本lua框架的一个核心,负责缓存项目中所有的“视图层”与“控制层”脚本。本脚本通过加载首个业务窗体(UIRootCtrl.lua)实现后续业务开发的持续运行。这里需要特别说明的是CtrlMgr.lua 脚本是负责缓存项目中所有控制层脚本的实例,以及提供控制层脚本访问的入口方法。


    ---
    ---  “lua框架”项目初始化
    ---
    ---   功能:
    ---      1: 引入项目中所有的视图层脚本
    ---      2: 通过CtrlMgr.lua (控制层)脚本,来缓存系统中所有其他控制层脚本。
    ---      3: 提供访问其他控制层脚本的入口函数。
    ---      4: 调用项目中第一个UI预设控制层脚本。
    ---
    ---
    --引入控制层管理器脚本
    require("CtrlMgr")

    ProjectInit={}
    local this=ProjectInit

    function ProjectInit.Init()
        --导入引入项目中所有的视图层脚本
        this.ImportAllViews()
        --lua控制器初始化
        CtrlMgr.Init()
        --加载UI‘根窗体’控制脚本
        CtrlMgr.StartProcess(CtrlName.UIRootCtrl)
    end

    --导入引入项目中所有的视图层脚本
    function ProjectInit.ImportAllViews()
        for i = 1, #ViewNames do
            require(tostring(ViewNames[i]))
        end
    end

           再往后的lua代码都与具体的业务功能实现有关系。基本都按照设计成对出现,例如本演示项目中的 UIRootCtrl.lua 与UIRootView.lua ,表示加载与显示UI根窗体。*Ctrl.lua定义玩家看不见的业务逻辑,例如加载与解析从服务器端传来的ab包资源,然后关于UI窗体内部的控件显示、显示方位、控件的事件注册等业务,都有*View.lua负责处理。这样实现了架构设计中的分层设计原理。
          最后值得说明的是,*View.lua 是负责显示具体3D/2D游戏预设资源的脚本。其内部定义预设显示的“方式”、“具体内容”与“行为”(包含事件注册)等。而本部分我们采用了xlua的映射技术,使得“lua显示”脚本具备了Unity的常用生命周期函数,进一步大大简化了lua编写业务的难度,例如定义了常见的:Awake()、Start()、Update()、OnDestroy()等函数。
          为了避免编写超长的技术博客文章,关于其他代码的具体实现部分,笔者在最后提供lua架构的演示项目下载链接,供广大有兴趣学员学习研究,共同进步。

    下载链接与二维码:
        链接:https://pan.baidu.com/s/1BobsN0c_4bBr1LSwF2li3Q
        提取码:bquu

  • 相关阅读:
    IP地址加时间戳加3位随机数
    你会想造一艘船吗?
    提问的智慧
    建造者模式
    设计模式(一)
    jeesite中activiti中的流程表梳理
    如何读书、学习?
    zxing生成高容错率二维码,以及添加文字
    LVM磁盘划分
    阿里云盘扩容(SUSE Linux下)
  • 原文地址:https://www.cnblogs.com/LiuGuozhu/p/10984871.html
Copyright © 2011-2022 走看看