lua 获取网络时间_Lua脚本语言的使用笔记

lua语言算是游戏行业中就热门的脚本语言了,所有从事游戏行业的程序员或多或少都有接触这门语言。但是lua这门语言又是争议性最大的语言,有的人对它恨之入骨,有的人把它奉上神坛,这究竟是什么原因导致对lua的评价形成了两个极端,而我们又应该如何去规避使用lua脚本语言将遇到的问题。

为什么有人把lua奉上神坛?

其实大量使用lua脚本的一般指的是 网络游戏行业,这个行业有个特点,就是运营商必须不停的提供新的玩法,以及对bug处理反应要非常迅速。

传统的编译语言就无法胜任这部分的内容,而脚本语言因为是通过文本解析来控制一些静态语言提供好的接口,以至于脚本代码的实质非常像策划的配置表。所以用了脚本语言之后运营商就可以快速对用户需求以及BUG进行处理迭代,从而保持自己的用户粘性,最后保证自己的稳定收益。而lua语言也因为行业内使用比较广泛,国内大神非常多,成功的项目数不胜数,从而使自己成为脚本语言的首选。

lua脚本语言的使用与引擎一点关系都没有,端游、cocos、unity、虚幻4都可以使用lua,很明显好好掌握这一门技能,无论游戏行业如何变化,lua都可以有用武之地。

为什么有人对lua语言恨之入骨?

在全行业都在研究lua语言的时候有一部分人并对lua仅仅停留在使用它进行热更新的层面,同时lua早期的研究BUG比较多,坑也不少。而程序员有个通病,如果被坑的很惨,就会对这个方案失去耐性,要么放弃lua要么做完一个项目后不再使用。

弱语言:lua代码作为弱类型的脚本语言代码,所以很难提供一个非常良好的代码编辑器。而且代码检测并不完善,成员变量不存在必须跑到对应的代码才能爆出来,所以BUG不断。

重构代价过高:很多人认为lua语言是个很容易上手的语言,又非常自由的语言。程序员如果非常有设计能力的话,可以写出来各种花样的代码,按照行业大佬的话:我只看得懂我写的lua代码。虽然放飞自我是一件好事,但是游戏项目毕竟是一个团体项目,好的代码往往以每个人能够快速理解做衡量。但是一旦某些团队不遵守这个原则对lua代码进行滥用的时候,往往会导致项目的人员不停更换,而后来者在重构lua代码的时候代价非常高,很容易导致项目被温水煮青蛙煮成青蛙汤了。

性能优化难度大:目前行业主流游戏仍然是手机游戏,而移动端的设备往往对性能要求非常高,而前几年市场上并没有什么良好的性能优化工具对lua代码进行检查。比如一个MMORPG对UI打开速度要求非常高,而UI的主要逻辑又写在lua这边,一旦界面打开卡顿,要进行优化无疑是一个非常痛苦的过程。如果没有什么好的解决方案很容易把项目给做死掉。

所以对于很多团队来说,在项目中大规模使用lua代码很有可能使项目处于一个难以把控的状态,总结下:用了lua后游戏可能因为弱语言不好重构调试、没有好的性能优化器的代价,导致游戏压根做不出来,这时候谈运营能带来多少好处的时候就没有太多意义了。

如何针对Lua脚本语言的痛点

最近几年lua编辑器、调试器、优化器的发展也是突飞猛进,然后加上lua脚本语言这种动态语言的优势,习惯了之后可以说使用lua进行项目开发比静态语言反而要快、优化上也更有优势。

下面介绍如何解决弱语言、调试器、性能优化器的问题

EmmyLua代码编辑器(idea插件,vscode据说也在开发)

https://github.com/EmmyLua/IntelliJ-EmmyLua​github.com https://www.cnblogs.com/sanyejun/p/9673198.html​www.cnblogs.com

qq群:1群29850775(已满),2群:529914962(已满),3群:805629309

这是一个多写注释就可以把代码从弱语言变成强语言的编辑器

主要掌握比较重要的doc注释语法:

对于C#的对象你可以声明为:

---@class Test
---@field public Size number
---@field public HashValue uint64
---@field public HashTime uint64
---@field public IsLoaded boolean
---@field public FileName string

然后任何一个地方你只要使用type的关键字将对于变量声明为Test,然后就能得到关键字提示

---@type Test
local t

如果一个函数返回为Test你可以声明为,在其他地方使用的时候就有点像C#的var语法

---@return Test
function getTest()
end

在项目的实际使用中要在C#函数导出、UI导出、配置表解析、网络协议、枚举定义上做好自动化的生成代码提示的工作。

其中C#函数导出你可以使用Emmylua群里面提供的做法进行

项目中的自动化生成范例:

UI导出

---@class LoginPanel
---@field PanelRef MoonClient.MLuaUIPanel
---@field txtVersion UnityEngine.UI.Text
---@field TxtAgreement UnityEngine.UI.Text
---@field Button_Visitor UnityEngine.UI.Button

---@return LoginPanel
---@param ctrl UIBase
function UIBind.BindLoginPanel(ctrl)
    return BindMLuaPanel(ctrl)
end

代码并不复杂,就是在UI的prefab上设置好要导出的组件,然后生成对应的提示API,最后把代码独立放在一个 lua文件中,在UI界面逻辑中调用一下Bind方法即可。

配置表导出:

每个配置表都生成一个对应的函数,然后使用return的doc语法进行配置生成,这样你的代码用起来就很爽了

---@class TaskConfig
---@field id number
---@field taskType number
---@field taskName string
---@field param1 number
---@field param2 number
---@field param3 number
---@field strParam1 string
---@field strParam2 string

---@return TaskConfig
---@param id number
function ConfigManager.GetTaskConfig(id)
    return taskConfigTable[id]
end

网络协议导出:

-- 发送
---@return usefirststring
---@param msgName string
function GetProtoBufSendTable(msgName)
end

-- 接收
---@return usefirststring
function ParseProtoBufToTable(msgName, datas)
end

这里我魔改了emmylua,使emmylua拥有了将第一个为字符串参数的类型解析为返回类型,魔改的代码可以去emmylua群里面,乐隐林上传的第三方emmylua进行试用。

使用emmylua插件的时候,一定要保证每个变量都能通过emmylua插件猜测到相应类型。多多使用type、param的代码注释。最后你会发现emmy通过注释把lua代码变成一个强类型代码。

emmylua插件如何进行调试:

emmylua官方插件因为idea插件市场的原因被强行拿掉了代码注入功能,目前使用require的方式加载lua的dll,然后进行远程调试。

教程:

057e2140631b109690d40e86c86a1a74.png

87a97c213206cee9db0f9c2ccbde36ec.png

游戏开始的时候运行对应的代码:

84c6c9f9a893abb7c55c01d4722ca903.png

然后在idea编辑器这边打开

4d0cbe50ea4ff434d06413b971ae7d21.png

打断点进游戏看效果。

当然你嫌弃麻烦可以,直接用我的第三方EmmyLua插件,直接Attach to Process,选择Unity即可。

a6b1af94ada12657ec8c7252247672aa.png

8ec6c1f66385fceb98f78309cc1654a6.png
https://github.com/ElPsyCongree/IntelliJ-EmmyLua​github.com

你会发现用起来比C#的调试器还方便一些。

Lua性能优化器:

https://github.com/ElPsyCongree/LuaProfiler-For-Unity​github.com

本人写的给Unity编辑器下使用的Lua 性能分析工具,只要你版本在Unity5.6以上都可以很方便的进行使用。

这是我在项目中得到的一些使用经验

使用此工具你将获得:

  1. 整体优化上可以获取函数的代码的调用信息,并针对进行排序,从而找出性能优化的切入点。
  2. 如果UI逻辑写在LUA,你可以通过此工具快速定位打开UI的卡顿点
  3. 快速定位update函数的gc产生情况,并针对这些函数做优化
  4. 查找lua函数的泄漏情况
  5. Record对每一次函数进行精细的分析,并且采样一段时间的样本进行综合分析 使用方法:

使用方法:

在Windows标签下,点开LuaProfilerWindow这个选项

bce8e914ff212a44b1930d18d3071909.png

在窗口下打开DeepLua

a93dc5b859bc994303d42216560735b5.png

最后进入游戏,就能获取到对应Lua函数的执行信息.

1、对Lua函数进行整体分析:

在代码框中输入 [lua]:,并点击右上角的merge按钮,最后点击对应的标签,进行排序就可以对Lua性能进行一个整体的分析,快速定位一些性能点。

8e481ee4609f631e8116e9b0a605aa99.png

2、优化UI中的逻辑卡点

打开UI前,将数据Clear一下,打开UI,暂停游戏,按照currentTime进行排序。

5f2a3ebad4bed53cbe93d9792c0ad903.png

3、快速定位函数的gc情况

根据TotalLuaMemory和LuaGC进行分析,直接眼睛看哪里的lua内存涨得飞快,就能很快得到要优化的函数了

fcaafcbc9ed4c16a38805ca16bebc325.png

4、查找一些函数泄漏

分三步走

002d9da5c5ec2dac47f6ecad09d822a7.png

1、在打开UI前进行MarkStaticRecord

2、打开UI后MarkLuaRecord

3、关闭UI后DiffRecord

查看Destroy Null Values 可以查看一些Unity这边已经销毁,但是Lua仍然持有的对象:

b6fa15a24907b43aa4cfeeadbfad7c44.png

查看remain 的values就能得到一些泄漏名单

c65d0d00d00769f76699736bd6c23be9.png

341bde3d962d38fdcbbd70eb26c825d6.png

总结:查找Lua泄漏大部分情况都是 委托泄漏,建议在销毁对象的时候把函数委托注销掉

5、Record对每一次函数进行精细的分析,并且采样一段时间的样本进行综合分析

主要目的是确定一个函数暴涨或者帧率下降点之中,lua函数干了些什么
使用方法:
1、点开DeepLua以及Record按钮,在想采样的地方点击StartRecord
2、选取一个内存暴涨的区间(先点击鼠标差不多选到一个位置,然后按键盘←→键)

dd9086614b5c1939ac92765a2ab4376c.png

然后你差不多就知道改如何优化这个区间了

优化帧率突然下降的点同理:

a4f02c3eee9ad740e58221ae17508435.png

最后谈一下使用Lua语言为什么会使项目的开发变得更快,优化更好做:

开发变得更快

使用C#代码的时候每一次修改代码,都要关闭游戏,然后编译一下代码,最后重进游戏,这个代码还是蛮高的。使用了Lua之后你至少不用重新编译代码,相对于C++作为代码开发的项目速度是精进了一层,相对C#来说也提升不少。

然后Lua代码甚至可以热重载,你不退出游戏,直接改了代码,逻辑就变了,我个人写了一个基于lua5.3的一个demo

https://github.com/ElPsyCongree/luareload-unity​github.com

b6506d4bcf81b58edbf17b782a5096df.gif

优化更加好做:

在使用静态语言的时候,服务器协议的序列化以及配置表的序列化的时候,要生成一大堆的配置表解析代码,这部分代码在大型项目非常容易被滥用,从而导致在代码编译的时候,这部分的text段以及内存的占用比较惊人,使用lua代码之后,因为lua的对象都是hash表,所以基本上不需要任何序列化的class,直接解析就好了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值