Unity中使用Lua时的动态刷新方案

7 篇文章 0 订阅

本文分享Unity中使用Lua时的动态刷新方案

相信Lua的使用大家已经不陌生了, 对于那些大部分逻辑使用lua的项目来说, 我们可以使用一个小技巧来提高日常的开发效率.

Lua文件的加载

Lua本身是解释执行的语言, 和C那些编译执行的语言不一样, 存在形式只是一个文本(当然也可以使用luajit预先编译).

一个Lua文件被称之为Chunk, 可以理解为是一个模块, 代码块.

使用require加载Lua文件之后, 会返回一张lua表或者返回true和false, 当然, 这取决于Lua文件的最后一个语句的写法.

------------------------------------
-- test1.lua
local t = {}
return t
------------------------------------
-- test2.lua
local t = {}
------------------------------------
-- main.lua
local t1 = require("test1")
local t2 = require("test2")
------------------------------------
print(t1)-- table: 000002AF947DDDE0
print(package.loaded.test1) -- table: 000002AF947DDDE0

print(t2) -- true
print(package.loaded.test2) -- true

如果Lua文件有返回值, require则返回该值, 并将该值存储在package.loaded表中, 表的key为lua文件名字(不带后缀).

如果Lua文件没有返回值, 且在require时没有出错, 则返回true, 并将true存储在package.loaded表中, 表的key为lua文件名字(不带后缀).

当我们再次使用require加载一个已经加载过的模块时, 会在package.loaded中查找, 如果存在则返回已经存储的值.

所以实际上只有第一次使用require时才真正的加载了模块, 后续的加载只是返回之前存储的值而已.

如果我们需要真正的进行重新加载, 需要先将package.loaded表中的值删除才行.

Lua文件的动态刷新

如果项目的大部分逻辑是由Lua编写, 我们不需要每次在修改之后进行: “停止Editor”=>“启动Editor”=>“经过一系列进入流程”=>“验证修改”. 只需要"刷新Lua"=>“验证修改”. 省去了前面的一系列流程, 从而提高效率.

这里的"刷新Lua"操作本身其实很简单, 就是将Lua模块从package.loaded中移除, 然后重新require即可.

我们可以将这个过程做成一个editor扩展, 使用快捷键一键搞定.

当然, 我们需要一个刷新方法, 一个刷新模块文件和一个编辑器扩展方法:

[MenuItem("Lua动态刷新 %#R")]
private static void RefreshLua()
{
    if (!Application.isPlaying) return;

    XLuaStart.Instance.DoString(string.Format("if RefreshModule then RefreshModule() end"));
}
function RemoveRequireCache(moduleName)
    package.loaded[moduleName] = nil
end

function RefreshModule()
    RemoveRequireCache("RefreshModuleFile")
    require("RefreshModuleFile")
end

------------------------------------
-- RefreshModuleFile.lua
RemoveRequireCache("test1")
local t = require("test1")

然后使用快捷键"Shift+Ctrl+R"就能进行刷新, 可以在RefreshModuleFile写测试代码来验证结果.

要注意的问题

在使用动态刷新的时候, 要注意需要刷新的模块是否存在全局引用, 比如:

  • 大部分情况下, 我们一般是将Lua脚本绑定到对应的预制, 然后在Lua中操作预制, Lua和预制存在引用
  • require之后的赋值给了一个全局的变量, 然后在业务代码中使用该变量

这些情况都需要先将引用移除, 不然使用的依然是之前存储的值.

说在最后

动态刷新的应用是很灵活的, 很多服务器也是通过这一特性来达到不重启的前提下更新内容.

本文分享的方案只是起到一个抛砖引玉的作用, 希望大家能够结合自己的需求来使用, 提高效率.

整个方案其实非常简单, 没什么更多的可以讨论的内容.

本来作者觉得这个方案应该很多项目都在使用, 并没有单独分享的必要.

作者进入当前的项目组后发现大家并不了解这方面的内容, 很多小伙伴之前可能没有研究过脚本语言的特性, 依然按照C#开发的模式来使用Lua, 没用充分将Lua的优势发挥出来.

而且我们的项目比较大, 每次重启, 进入目标点起码要花费2分钟以上, 日积月累下来浪费的时间是很恐怖的.

所以在和项目组的小伙伴们分享后, 也决定发布到网上, 希望对大家有所帮助.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拂面清风三点水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值