2019-04-20

热更新实现方式:

        1、使用Lua脚本编写游戏的UI或者其他逻辑,Lua是一个精悍小巧的脚本语言,可以跨平台运行解析,而且不需要编译过程。

        2、使用C#Light

        3、使用C#反射技术

关于AssetBundle

       Unity提供了一个资源更新技术,就是通过AssetBundle,我们可以通过AssetBundle更新游戏UI,也可以把脚本或者其他代码当成资源打包成AssetBundle然后更新到客户端。

       在所有的热更新技术中都需要AssetBundle.

Lua热更新原理

      在移动端可以编写Lua的解析器,通过这个解析器,可以运行最新的Lua脚本,然后我们把控制游戏逻辑的代码都写成Lua脚本。

Lua工具

  1、Lua官网 Lua.org

  2、Luaforwindows

            http://luaforge.net/projects/luaforwindows/

           http://luaforwindows.luaforge.net/(可安装的exe文件,一整套的lua开发环境,有lua的解析器,参考手册,范例和库,文档和编辑器)

3、安装Luaforwindows,关于Luaforwindows的目录介绍

                                    Lua编程

从Hello World开始:print("Hello World!")

注:1.print()是lua内置的方法

        2.在lua中字符串用“”或者‘’都可以表示

        3.lua中每条语句后面是没有;结尾的

定义变量

  num = 100

           这里定义了一个全局变量叫做num,赋值为100

          在lua中定义变量是没有类型的,根据存储什么数据,来决定是什么类型

          变量的命名不能以数字开头

          变量避免下划线加大字母开头,这种格式Lua自身保留

          推荐使用C#中的命名规范和驼峰命名

注释

        1、单行注释 --

        2、多行注释  --【【   这里是注释内容 】】--

变量类型

   1、nil表示空数据,等同于null

   2、boolean 布尔类型,存储true和false

   3、string 字符串类型,字符串可以双引号也可以使用单引号表示

   4、number小数类型(lua中没有整数类型)

    5、table表类型

               myTable={34,34,2,342,8}

               myTable[3]

所有从1开始

我们可以使用type()来取得一变量的类型

局部变量和全局变量

   默认定义的变量都是全局变量,定义局部变量需要在前面加一个local;

   在代码块中声明的局部变量,当代码块运行结束的时候,这个变量就会被释放。

  eg: temp = 34

           local var = 555

运算符

            1、算数运算符 + - * 、 %(lua中没有++ --)

            2、关系运算符 <= < > >= ==

            3、逻辑运算符 and or not 分别表示 与 或 非 (类似于C#中的&& || !)

流程控制

if语句

注:if后面必then

1、if [condition] then

      end

2、if [ condition] then

     else

    end

3、 if [condition] then

elseif [condition] then

      else

      end

循环结构while循环

    1、while语法结构

while [condition]  do

           end

  repeat 循环

1、语法结构 (相当于 do - while())

             repeat

                 [code to execute]

           until[condition]

for循环结构

for index=[start],[end] do

                           [code to execute]

        end

  注:break可以终止循环  没有continue语法

函数

   定义函数

         function [function name](param1,param2)

                           [function code]

         end

标准库(标准函数)

      lua内置提供了一些常用的函数帮助我们开发

        1、数学处理的math相关函数

        2、字符串处理的string相关函数

       3、表处理的table相关函数

            在lua中的table类似C#中的字典,其实就是一个key-value键值对的数据结构。

第一种创建方式

             1.table的创建

                 myTable = {}

                表名后面使用{}赋值,表示一个空的表

           2.table的赋值

                  myTable[3] = 34 当键是一个数字的时候的赋值方式

                 myTable["name"] = "taikr" 当键是一个字符串的赋值方式

                myTable.name = "jianguang" 当键是一个字符串的赋值方式

           3.table的访问

                   myTable[3] 当键是数字的时候,值有这一种访问方式

                   myTble.name  当键是字符串的时候有两种访问方式

myTable["name"]

第二种创建方式

                      myTable = {name="dalian",age = 18,isMan = false}

                         (创建表之后依然不可以添加数据)

                     数据访问

                               myTable.name

                               myTable["name"]

              第三种创建方式

                          myTable = (31,55,68)

                          当没有键的时候,编译器会默认给每一值,添加一数字键,该键从1开始

       4、文件操作的io相关函数

                                                  通过表来实现面向对象

   myTable = {} 申明对象

   local this = myTable 申明this关键字代表当前对象

   --定义并声明对象中的属性

   myTable,name = "jianguang"

   myTable.age = 110

--定义并声明对象中的方法

  myTable.function = function()

              [code to execute]

end

function myTable.function()

         [code to execute]

end

LuaInterface

    LuaInterface 包括两个核心库 一个是LuaInterface.dll,一个是Luanet.dll,我们可以通过LuaInterface完成Lua和C#(CLR)之间的互相调用。

eg:创建LuaInterface项目,把 luainterface.dll 和luanet.dll添加到项目中

添加引用

代码:(引用命名空间)

运行结果:

在C#中执行访问Lua代码

    Lua lua = new Lua(); //创建Lua解析器

   lua["num"] = 5; //定义一个 num

  lua["str"] = "a string"; //定义一个字符串

  lua.newTable("tab"); //创建一个表 tab={}

取得Lua环境中的变量

   double num = (double)lua["num"];

   string str = (string)lua["str"];

在C#脚本中执行Lua脚本文件,或者脚本字符串

   lua.DoFile("script.lua");//执行script.lua脚本

lua.DoString("num = 2");//执行lua代码

  lua.DoString("str = 'a string'");

  object[] retVals = lua.DoString("return num,str");

在热更新中,只需要写好解析Lua脚本的代码,然后C#代码不需要变动,只需要修改lua脚本就好,通过lua脚本控制游戏逻辑

Lua 和 C#中类型的对应

           nil                       null

            String                system.String

            number               System.Double

            boolean               System.Boolean

             table                    Lualnterface.LuaTable

           function                 LuaInterface.LuaTable

 把一个C#方法注册进Lua的一个全局方法

            //把一个类中的普通方法注册进去

            Lua.RegisterFunction("NormalMethod",obj,obj.GetType().GetMethod("NormalMethod"))

lua.DoString("NormalMethod()")

  //把一个类的静态方法注册进去

   lua.RegisterFunction("StaticMethod",null,typeof(ClassName).GetMethod("StaticMethod"))

 lua.DoString("StaticMethod()")

在Lua中使用C#脚本

  require "luanet"

  --加载CLR的类型、实例化CLR对象

  luanet.load_assembly("System.Windows.Forms")

  luanet.load_assembly("System.Drawing")

  Form = luanet.import_type("System.Windows.Forms.Form")

  StartPosition = luanet.import_type("System.Windows.Forms.FormStartPosition")

  print(Form)

  print(StartPosition)

  在Lua中使用C#中的类创建对象的时候,会自动匹配最合适的构造方法。

在Lua中访问C#中的属性和方法

   Lua代码中,访问C#对象的属性的方法和访问table的键索引一样,比如obj.name 或者 obj["name"]

  Lua代码中,访问C#对象的普通函数的方式和调用table的函数一样,如:obj:method()

注:在Lua中访问C#中的方法 - 特殊情况

当函数中有out或者ref参数时,out参数和ref参数和函数的返回值一起返回,并且调用的时候,out参数不需要传参

注:Lua中的调用和返回值  out参数不需要参数,这个返回一个table. ref参数需要传入参 数,返回一个table.

                                      AssetBundle

      参考我的文章 Unity之AssetBundle

                            uLua simpleframework

把框架导入项目中

           我们首先需要做,点击菜单栏Lua - Welcome Screen 取消开始时候显示对话框,然后 Clear LuaBinder File + Wrap Files.然后点Gen Lua Wrap Files生成包装文件,把C#里的一些类包装成Lua里的Table,包装类会把自身注册到Lua的环境里。(先Clear 后 生成)

菜单栏Game  是用来Buile AssetBundle的。Buile 相应的平台,Project下会生成StreamingAssets文件夹,所有动态更新的资源都会打包到这个文件夹下。

生成游戏物体

在C#中访问Lua中的变量

方法一

方法二:

执行Lua脚本文件,调用Lua方法,在Lua中使用协程

     调用Lua脚本,方法一

调用Lua脚本方法二

调用Lua方法

方法一:

方法二:

在Lua中使用协程

框架使用

框架采用了Pure MVC的架构,GlobalGenerator整个项目的启动器。

然后进入StartUp()方法(管理类)

注册的时候会调用StartUpCommand,F12点进去了解一下

我们来看一下GameManager中对资源的更新处理

然后我们来看一下Lua的代码结构:

View:视图的一些代码

System:和Unity对应的一些类

Logic:对应的逻辑类

Controller:控制UI的类

Common:共有的类

3rd:一些开源项目案例

                                                                     热更新案列

首先我们来做一个界面

然后我们进行打包,我们把BottomPanel和SettingPanel拉成预设体,并设置bundle属性,bottom.assetbundle 和 setting.assetbundle

注:框架属性命名格式定我  名字.assetbundle

因为引用 : 所以我们把图片打成一个包字体打成一个包(一般情况下我们会把同一个界面的图片打成一个包,具体按公司要求来)

sprite.assetbundle  和 font.assetbundle

然后我们打成win下的bundle

然后我们新建一个空物体并命名为GlobalGenerator,并挂上脚本GlobalGenerator

GloabalGenerator脚本的代码我们不需要修改,作用:创建GameManage,然后进行初始化

GameManage的代码我们需要修改一下,把LuaManage.DoFile("Logic/GameManager")中的GameManger改成我们调用的Lua脚本名称,在这里我们就不改了,把原来的GameManager改成GameManager_back,自己再创建一个Lua脚本GameManager

新lua的GameManager代码如下

然后我们需要做的就是写View视图下的BottomPanel脚本

然后我们回到Unity编辑器给Bg添加动画

选择Window ->Animation -> Create - >命名为SettingsPanel(由做一个小变大的动画),调节Scale属性

刚开始的时候设为 0 0 0 如下

60帧的时候变为 1 1 1

这是我创建面板由小变大的一个动画,下面我们来场景面板隐藏的动画 点击右上角 SettingsPanel - 》create new clip...  创建一个新的动画 SettiongsPanelHide

创建步骤何第一个动画一样,0帧的时候大小为1 1 1 60帧的时候大小为 0 0 0

然后我们来设置一下状态机

我们在SettingPanel面板设置一个关闭按钮,而SettingPanel默认是不显示的,然后把SettingPanel面板的Bg的Scale设为0 0 0

   然后我们来写Lua View视图中SettingsPanel.lua

视图层写好,我们来写控制层Controller 下 BottomCtl 和 SettingsCtrl  来对相应视图控制

然后我们的代码热更新就做好了

作者:歪歪小花鹿

链接:https://www.jianshu.com/p/7a0b78650733

来源:

你可能感兴趣的:(2019-04-20)