【教程】LuaEngine开发教程(二) - 编写简单脚本上

上篇教程这回教大家来写一个简单的脚本来入门LuaEngine开发。开发Lua脚本可以使用任意文本编辑工具(记事本都行),这里演示时使用的工具是vscode。本篇教程我们的目标是配置好开发脚本的环境,并且写一个使用快捷键进行定点传送的简单Mod,接下来的内容均以你已经了解lua语言的基本用法为基础,如果你还不了解,请自行移步菜鸟去入个门(不用学太深)。

第一步是修改配置文件打开前置的命令窗口,使得我们开发脚本更加方便,打开游戏根目录的loader-config.json文件,修改logLevel的值改为INFO,保存文件。

第二步我们来创建一个新的lua脚本,进入游戏根本目录下的Lua文件夹,此时文件夹中包含了Engine.lua和modules文件夹,这是LuaEngine的引擎文件,今天的脚本我们先不用这些。下面,我们在Lua目录下新建一个test.lua的文件。

第三步开始,我们将编写lua脚本,打开我们上一步建立的test.lua文件,在里面写入function on_time() end

on_time函数将会在游戏过程中每次时间变更时被调用,基本可以理解为实时在运行的函数。

下面我们要梳理一下我们本次开发的脚本要实现的功能,按下快捷键(这里我们选择小键盘1为记录坐标点,小键盘2为传送)记录和传送到坐标点。

首先我们需要一个检测是否按下快捷键的功能,LuaEngine内置了CheckKeyIsPressed(number key)的函数用于检测某个键是否被按下,我们可以使用这个功能来实现目标。

根据查询vk表,我们得知小键盘1为97小键盘2为98,我们先写一个功能,检测到按下小键盘1输出文字“记录”按下小键盘2输出“传送”。

写好这些后,我们打开游戏,首先我们可以看到前置的命令窗口出现了,接下来我们要输出的内容就会显示在这里,我们读档进入游戏,然后按下小键盘1,不出意外的话,你可以看到命令窗口已经显示了很多的“记录”。这是由于我们按下过程中,print一直会被触发导致的,这里我们要修改一下代码,添加一个触发延迟,这里我们可以使用LuaEngine内置的计时器功能AddChronoscope(float time, string name)、CheckChronoscope(string name)、CheckPresenceChronoscope(string name)来实现(也可以使用lua内置的时间函数来手动实现计时器)。

此时我们就限制了输出文字的功能在每1秒内只被允许执行一次,我们在游戏中的聊天窗口输入reload test来重载脚本(reload 脚本名 可以重载脚本)看看效果,如果一切正常,你再次按下小键盘1时,命令窗口将会以每秒一次的频率输出“记录”。

至此我们已经写好了触发记录坐标和触发传送的快捷键功能了,接下来我们来写记录坐标和传送的功能。

首先我们通过ct表可知玩家当前的位置坐标偏移如下

xyz轴的偏移分别是160,164,168,数据类型是浮点,接下来我们创建一个table变量用于记录这三个轴的坐标。然后创建两个函数来记录和写入坐标。

首先是记录坐标用的变量,如果你还未学到lua的table,可以直接创建三个独立的变量,不过建议还是先看下table的基本用法。

这里可以看到外面将PlayerPos变量定义在了on_time外面,这样这个变量将在当前脚本全局可用,且不会应为每次调用on_time而被刷新掉。

接下来是定义两个函数,分别用于记录玩家当前位置和修改玩家当前位置,这里我们用到了LuaEngine的内存读取函数GetAddress(hex base, {hex offset, ...})、GetAddressData(hex addr,string type)和内存修改函数SetAddressData(hex addr,string type,value),并将着两个函数替换掉原来的输出文字。

这里我们先看记录玩家坐标的函数,首先根据ct表我们得知,玩家的坐标位于玩家实体下偏移了160,我们先要获取玩家实体的地址,这里我们使用GetAddress功能,基址填入0x145011760,指针部分是一个table,需要分别填入每一级的指针,此处我们参考ct表,玩家实体的指针只有一级,我们填入{0x50}即可。

然后我们判断一下这个地址是否存在,当获取地址时如果LuaEngine获取失败将返回false的布尔型数据,此处我们直接if进行判断即可,然后我们将玩家三轴的坐标数据分别用GetAddressData获取并存入PlayerPos变量,GetAddressData的第一个参数为要读取的地址,根据ct表我们得知玩家的x轴坐标为【玩家实体地址+160】,所以这里我们填写刚刚获取的玩家实体地址+160即可,第二个参数为数据类型,根据ct表我们知道数据类型是浮点也就是'float'。到此我们记录玩家坐标的函数就写好了。

接下来我们来看修改玩家坐标的函数,同样的我们先获取玩家实体地址,然后我们进行一下判断,看看是否已经记录了坐标,还记得我们创建PlayerPos是给的每个轴的初始值都是nil吗,这代表空值的意思,我们可用判断这三个值是否为空来判断是否记录了坐标。当存在记录坐标并且玩家实体也存在时,我们使用SetAddressData分别设置三个轴的坐标,SetAddressData的使用方法和GetAddressData基本一致,额外的第三个参数是要设置的值。

现在我们在游戏中再次重载脚本,还记得怎么操作吗,reload test 我们前往训练区域去试试,首先按下小键盘1记录坐标,然后走两步,按下小键盘2,如果一切正常,现在我们传送回去了。

到此,我们的核心功能就已经写好了,不过这个脚本还存在一些问题。大家想想如果此时切换地图,PlayerPos记录的坐标是否还是有效的坐标呐?玩家被传送时是否会被墙挡住呐?这些我们留到下期再讲。

by Alcedo 更新于 2024-01-10
打赏后可直接下载附件 赠人玫瑰 手留余香
1个大佬推荐该主题
默认
最新
1