Unity3D热更新技术点——ToLua

Posted 游戏蛮牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity3D热更新技术点——ToLua相关的知识,希望对你有一定的参考价值。

中我们通过一个小的案例,介绍了ToLua在Unity中的基本使用方法,而这次,我们将通过一个更为复杂的例子,继续深入了解ToLua的使用方法及其原理。


ToLua文件目录

我们首先来了解一下ToLua的文件目录。

Tolua集成主要分为两部分,一部分是运行时需要的代码包括一些手写的和自动生成的绑定代码,另一部分是编辑器相关代码,主要提供代码生成、编译lua文件等操作,具体就是Unity编辑器中提供的功能。


接下来我们具体介绍一下Tolua文件列表中文件的用途:


1.Editor

Editor下Custom/CustomSettings.cs 自定义配置文件,用于定义哪些类作为静态类型、哪些类需要导出、哪些附加委托需要导出等


我们需要注册到Lua中的类型也都需要在这里导入,在Tolua中已经为我们提供了Unity大部分基础类型,若我们需要导入自己的类型或Tolua没有导入的类型可以在其中添加,如下图所示: 


2.Source

在Source文件夹中有Generate文件夹及LuaConst.cs脚本,Generate中主要是生成用于交互的绑定代码wrap脚本,LuaConst.cs是一些lua路径等配置文件。 若在CustomSettings中做了修改,需要在菜单栏的Lua选项中,重新生成的Wrap文件,当重新生成Wrap文件后,会发现我们新添加类型也生成了相应的Wrap文件,如下图所示:

Unity3D热更新技术点——ToLua(2)

Clear wrap files后会自动重新生成wrap文件


Unity3D热更新技术点——ToLua(2) 

3.ToLua

Tolua文件夹中有如下文件

1)BaseType: 一些基础类型的绑定代码


2)Core: 提供的一些核心功能,包括封装的「LuaFunction」「LuaTable」 「LuaThread」「LuaState」「LuaEvent」、调用tolua原生代码等等。


3)Examples: Tolua示例


4)Misc: 杂项,包含LuaClient,LuaCoroutine(协程),LuaLooper(用于tick),LuaResLoader(用于加载lua文件)


5)Reflection: 反射相关


我们这里只了解一下Tolua中的文件结构及相关文件的作用,具体的脚本绑定及生成流程我们不做过多赘述,如需要了解可以查询相关资料,若有较多反馈,在之后我们可以开一篇新的文章,具体介绍tolua 


Tolua跳一跳

现在我们已经大致了解了Tolua这个方案,接下来我们通过一个Demo,来看在Unity中,我们如何使用Tolua开发项目。


本文中以一个仿照微信跳一跳的小游戏作为案例来讲解,案例非常简单,但希望读者有unity基础,本文主要讲解Tolua的用法,代码逻辑方面的讲解可能会相对偏少 

Unity3D热更新技术点——ToLua(2)


一.开发前准备

在之前,我们已经导入了Tolua资源。在这个项目中,我们需要使用到DoTween插件,可以在Asset Store自行下载。

Unity3D热更新技术点——ToLua(2)


二.Lua虚拟机管理器

我们需要用C#脚本来开启Lua虚拟机并调用Lua模块,那么不同的逻辑就会有不同的C#脚本来开启虚拟机并调用Lua模块,这无疑是很耗费性能且繁琐的,所以我们可以自己做一些封装,先将C#脚本中所必须的方法做一个缓存,如下代码所示: LuaManager.cs

Unity3D热更新技术点——ToLua(2)

在代码中,我们直接使用LuaClient,LuaClient我们可以理解成是ToLua内部对自己的一种封装,可以视为tolua环境的一个启动。我们需要将LuaClient中的protected LuaState luaState = null;改为public,同时我们可以在LuaClient中再封装一个调用Lua模块函数的方法。


Unity3D热更新技术点——ToLua(2)

然后我们在场景中创建一个空物体,添加LuaManager.cs脚本


Unity3D热更新技术点——ToLua(2)


三.自建C#方法工具类

在使用Tolua开发中,ToLua提供的方法有限,有时我们可能找不到很好的方法来代替C#中的功能,或者不清楚某个功能的使用方法,这时候我们可以在C#中封装好一些功能,然后导入到Lua中,便可以直接在Lua中使用。这里可以创建一个C#脚本,我们命名为Util.cs,因为Lua中数值只存在number类型,如果需要我们可以封装int和float类型


Unity3D热更新技术点——ToLua(2)

同时还有我们可能需要使用到的Dotween的部分方法


Unity3D热更新技术点——ToLua(2)

之前我们介绍过,如果需要添加导入lua的类型,需要在CustomSettings.cs中添加

Unity3D热更新技术点——ToLua(2)

可以看到我们在其中加入了 _GT(typeof(Util)),然后重新生成wrap文件 


Unity3D热更新技术点——ToLua(2)


如图所示,Source/Generate中生成了UtilWrap文件


四.开始界面

再之前的动图中可以看到我们的项目中的开始界面,只搭建了背景及一个开始按钮,读者也可以自行扩展。 * 这里我们需要用到Button事件,我们同样可以通过封装一个C#脚本给lua提供一个按钮事件


BtnEvent.cs 

Unity3D热更新技术点——ToLua(2)


接下来就是在lua中的调用了。 我们可以在Project面板中找到lua文件夹,我们可以把我们的Lua脚本文件放在这个文件夹下(当然,也可以根据自己的习惯修改Lua文件夹,但我们查找Lua文件的路径就需要修改),文件夹下有名为Main.lua的Lua文件,在这个脚本中,我们可以定义我们所需的全局类型:

Unity3D热更新技术点——ToLua(2)


然后我们创建Login.lua,我们的开始界面逻辑将会写在这个脚本中:

Unity3D热更新技术点——ToLua(2)


在这个lua脚本中,可以看出,其实Lua中调用unity的方法和C#十分相似,想必有Unity基础的读者很容易看明白以上的代码。 
其中要注意的是,unity中的物体无法绑定lua脚本,所以无法通过如c#中定义public的值可以在Inspector面板进行赋值,所以代码中我们必须通过GameObject.Find()或者Transform:Find()来找到物体

还有一个重要的地方,需要注意我们调用类的方法、属性、字段时「.」和「:」的区别

我们希望在游戏中有背景音乐,所以在这里,我们使用协程来下载一首音乐,并挂之前创建的在Manager上

Unity3D热更新技术点——ToLua(2)接下来我们来看如何在C#中调用刚才写好的lua模块:


Unity3D热更新技术点——ToLua(2)


四.角色逻辑

开始游戏界面完成后,我们就着手于游戏主场景,首先我们可以新建场景,使用plane、cube等基础物体,搭建一个简单的跳一跳场景。

Unity3D热更新技术点——ToLua(2) 

接下来,我们用Lua实现角色的跳跃,这里我们可以使用刚体来让角色实现向前跳跃的动作:

Unity3D热更新技术点——ToLua(2)


同样的,首先我们要找到角色,然后获取其中的刚体组建。 

在跳一跳游戏中,我们通过某一个按键(这里我们使用空格键)让角色开始跳跃,角色跳跃的力度是更具按下屏幕或者按钮的时间来决定的,所以这里我们需要获取到我们按下按钮的时间

Unity3D热更新技术点——ToLua(2)


然后实现角色在蓄力(也就是按住按钮)时的动作,以及粒子效果,如下图所示

我们的角色是由一个圆柱体和一个球体组成,所以在蓄力时,我们需要压缩圆柱体同时球体的位置也要下移:


Unity3D热更新技术点——ToLua(2)


在这里,body时角色的身体,head时头部,我们都需要先找到物体然后在对其进行操作 

蓄力时的粒子效果,读者可以自行在unity中编辑,这里就不做过多赘述,相关代码如下:


particle : GetComponent(‘ParticleSystem’) : Play()

我们应该在按下空格时就开启粒子,所以这里应该放在判断按下空格中 

当我们松开空格时,角色需要恢复之前的大小及位置,粒子效果也需要停止,同时角色跳跃。


Unity3D热更新技术点——ToLua(2)


这里我们用DoTween来恢复角色大小。 

关于角色的逻辑,最后一步就是判定角色是否跳到了下一个盒子


Unity3D热更新技术点——ToLua(2)


在这里我们角色如果跳到了下一个盒子,就会给当前盒子添加一个脚本,并移动摄像机,如果没有跳到则打开一个ui界面,并调用一个叫Continue的模块 


Unity3D热更新技术点——ToLua(2) 

Continue.lua 

Unity3D热更新技术点——ToLua(2)


最后就是角色控制的C#代码,和之前开始界面类似,不过这里多了Update和OnCollisionStay

Unity3D热更新技术点——ToLua(2)


上面提到了会给跳到的盒子加入一个脚本,那么接下来我们就来看关于盒子的逻辑 

五.盒子逻辑

首先,当角色跳到当前盒子上,我们就应该把这个脚本绑定到该盒子,再之前角色的逻辑中已经有说明。我们可以在图中可以看到,当按下空格,角色压缩是盒子也会同时被压缩,松开空格后盒子复原

Unity3D热更新技术点——ToLua(2)

Unity3D热更新技术点——ToLua(2)


然后当角色跳到新的盒子上,就应该根据当前位置,生成一个新的大小和颜色随机的盒子,具体代码逻辑如下

Unity3D热更新技术点——ToLua(2)


最后一步,就是删除之前的盒子,我们可以判断盒子是否在摄像机范围内(在本项目中,我们摄像机范围内应该只有两个盒子,当前和新生成的盒子),不在摄像机范围内的盒子,我们可以将其删除

Unity3D热更新技术点——ToLua(2)

BoxControl.cs 

Unity3D热更新技术点——ToLua(2)

到此为止,我们使用Tolua制作的跳一跳小游戏就完成了。项目虽小,但包含了Tolua的大部分功能的常见使用方法。

知乎@朔宇


以上是关于Unity3D热更新技术点——ToLua的主要内容,如果未能解决你的问题,请参考以下文章

游戏开发框架自制Unity通用游戏框架UnityXFramework,详细教程(Unity3D技能树 | tolua | 框架 | 热更新)

Unity3D热更新之LuaFramework篇[02]--用Lua创建自己的面板

游戏开发高阶从零到一教你Unity使用ToLua实现热更新(含Demo工程 | LuaFramework | 增量 | HotUpdate)

游戏开发高阶从零到一教你Unity使用ToLua实现热更新(含Demo工程 | LuaFramework | 增量 | HotUpdate)

unity引擎热更新流程(主要是资源加载方面)--unity+tolua

体验ToLua框架下热更新(Phpstudy)