lua游戏开发实践指南光盘_【Unity游戏开发】Lua更新运行时代码

最近沉迷lua脚本热更,想说这个可以提高多少菜鸡的调试效率,找了网上好多文章,但是都不行,尝试了很久,并且自己测试和学习,写了一遍,勉强能热更了。下面记录一下热更Lua的过程。

一、用来卸载表格的加载

最简单粗暴的热更新就是将package.loaded[modelname]的值置为nil,强制重新加载:

function 

这样做虽然能完成热更,但问题是已经引用了该模块的地方不会得到更新, 因此我们需要将引用该模块的地方的值也做对应的更新。

function 

二、我认为逻辑最清晰的,但是可能是我不会用吧!

源链接:链接

--region 利用_ENV环境,在加载的时候把数据加载到_ENV下,然后再通过对比的方式修改_G底下的值,从而实现热更新,函数 -- 失败

三、有点复杂,递归了debug.getregistry(),然后去替换旧的值

源链接:http://asqbtcupid.github.io/luahotupdate1-require/ 有介绍原理,讲得还蛮细的,学习了蛮多,但是这个递归真的是复杂,我注释掉了一些递归,能满足基本的需求。

local 

我跟老大炫耀的时候,老大说,那你懂其中的原理吗,一下问懵我了,老大说,你要学习到其中的原理才能进步啊,不然就只是个会用工具的人。好有道理,搞得我羞愧难当,赶紧好好学习其中原理。

Upvalue

Upvalue 是指那些函数外被引用到的local变量,比如:
local 
那么a就是这个foo的upvalue。

getupvalue (f, up)

此函数返回函数 f 的第 up 个上值的名字和值。 如果该函数没有那个上值,返回 nil 。
以 '(' (开括号)打头的变量名表示没有名字的变量 (去除了调试信息的代码块)。

setupvalue (f, up, value):

这个函数将 value 设为函数 f 的第 up 个上值。 如果函数没有那个上值,返回 nil 否则,返回该上值的名字。

_G和debug.getregistry这2张表

学习的时候,我一直以为只有把_G这张全局表的旧值替换掉就好了,然后真正实施的时候,还是会有种种问题,实在是很糟糕,看这段代码的时候一直不是很理解,看了debug.getregistry的定义:debug.getregistry():返回注册表表,这是一个预定义出来的表, 可以用来保存任何 C 代码想保存的 Lua 值。
还是半桶水,但是我有注意到_G这种表其实在debug.getregistry返回的这张注册表里有,所以最后就递归这张表其替换里面的旧值就好了。

getfenv(object):返回对象的环境变量。
setfenv(function,_ENV):设置一段代码的运行环境

io.popen("dir /S/B /A:A ""..RootPath.."""):获取一个File对象其下的所有文件和目录的绝对路径: 的所有文件(/S/B),不包括文件夹(/A:A),io.popen返回文件句柄file handle

对了,InitFileMap这个函数有个要注意的,luaPath在保存的时候是按文件夹路径保存的比如:game.modules.XXX.lua,所以可能要自己搞对这个路径;

最后总结一下流程:

1. 初始化需要热更的文件路径,用一张哈希表存下来;
2. 然后遍历这些路径,读取所有的代码,判断是否是新代码,新的话记录到ChangedFuncList列表里面;3. 新代码的话,就把加载的字符串放置在空环境了,防止报错setfenv(NewFunction, ReloadUtil.FakeENV);4. 代替旧代码,拿着ChangedFuncList列表到注册表(debug.getregistry())里面去找旧值,递归注册表的旧值替换成新的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值