一.Unlua用途
1.用代码代替蓝图,多人开发易维护
2.热更新,直接修改出效果。玩家感受不到
二.直接看案例
1.去GitHub上,把工程下Donwn下来
我这用的是UnLua-2.3.6。 因为我想直接适配5.3。更高版本,有时需要自己手动改,也可以用别人改好的。(注意2.4.0,可能不直接支持5.3,是不是很反常识)

三.开抄
案例1 HelloWorld
1.首先打开TPSProject工程,打开01,建个个空的LuaHelloWorld。把GameMode也设置成GameModeBase.

2.打开关卡蓝图,开始Bind。因为至少要bind一个有反射的,你才有用武之地。关卡本质也是actor嘛。
下面这句是AI说的
关卡蓝图(Level Blueprint)在底层逻辑上可以被视为一种特殊的 Actor(准确说是继承自 AActor 的 ALevelScriptActor),但在实际使用中,它更像一个关卡专属的"全局事件图表",而非一个能自由放置的普通 Actor。

当你Bind后,会自动生成这个GetMoudleName。它就是来读你脚本的。

AI解释如下

3.这个时候,你写上自己的路径。Tutorials.02_HelloWorld。就是在Tutorials 玩家夹下,一个叫02_HelloWorld的lua脚本。
再点创建模板。

查看


4.打开VSCdoe 工作区,开敲
官方案例:

我们拿到的是这样的

5.看懂,然后模仿
Lua
local Screen = require "Tutorials.Screen"
AI话
1.require 是Lua的模块加载函数。这一行加载了一个名为 Tutorials.Screen 的模块(. 表示路径分隔符,实际对应 Content/Script/Tutorials/Screen.lua 文件),并把返回的内容赋值给局部变量 Screen。Screen 模块是UnLua教程中封装的一个辅助工具,它的 Print 方法可以在游戏画面上 显示文字,类似UE蓝图中的 "Print String" 节点。注意:这个 Screen 并非UE引擎自带的API,而是教程专用的辅助模块。
人话:就是引入Unlua输出到屏幕的模块,这个不是自带的。
Lua
local Screen = require "Tutorials.Screen"
这一行创建了一个UnLua类 (可以理解为一个"Lua脚本模板"),并将其赋值给局部变量 M。UnLua.Class() 是UnLua提供的核心API,它会生成一个具备UE绑定能力的Lua表,后续我们可以向这个表添加方法(比如 Initialize),最后返回给UnLua使用。
这里 M 只是一个约定俗成的变量名(Module的首字母),你可以改成任何名字。
人话就是: 必须要的对象,统一开头。没这个类就没得玩了,它里面有大量unluaAPI。
UnLua.Class() 本身只是生成一个普通的Lua表 ,真正让它"有魔法"的是最后 return M 给UnLua框架 。UnLua拿到这个表之后,会把UE对象和这个表绑定在一起,然后表里的 Initialize、ReceiveTick 等方法才会被自动调用。所以确实可以理解为"固定开头模板",不写就没法绑定。
3
Lua
function M:Initialize()
local msg = [[
Hello World!
------ 本示例来自 "Content/Script/Tutorials/01_HelloWorld.lua"
]]
print(msg)
Screen.Print(msg)
end
这个注释非常关键,它说明了UnLua的生命周期机制:当UE中的蓝图或C++对象被绑定到Lua脚本后,该对象在游戏运行时被创建时,UnLua会自动调用 这个Lua脚本中的 Initialize 方法。
你可以把它理解为UE中 "BeginPlay" 的Lua版本,适合在这里做一些初始化工作。
在Lua中,function M:Initialize() 是实例方法 的定义语法。冒号 : 会自动传递一个隐藏的 self 参数,代表当前正在执行此方法的对象实例。
|--------------|---------------------------------|
| Initialize | 绑定对象的生命周期初始化函数,由UnLua在对象创建时自动调用 |
这里的 self 会指向绑定了这个Lua脚本的UE对象 (比如一个蓝图Actor),通过 self 你可以调用该对象的UE函数和属性。
人话: 就是绑定后,self就是UE的对象。这里相当于重写BeginPlay().
Initialize 的调用时机比 BeginPlay 更早 ,发生在对象刚构造、还未开始Play的时候,所以适合做一些纯初始化工作。如果你想在真正的"游戏开始"时机做事,更准确的对应方法是 ReceiveBeginPlay(也是在Lua里写同名函数即可)。
6.开始写自己的
模板放开一些函数就能用。这里有个坑点,不要太相信提示。Screen.Print,P要大写
Lua
local Screen = require "Tutorials.Screen"
local M = UnLua.Class()
--require Screen
function M:Initialize()
local msg = [[
Man!
]]
local msg2 = [[ Manba Out!]]
print(msg)
Screen.Print(msg);
Screen.Print(msg2);
end

我有点好奇为啥一直,在屏幕上。它这个print不是完全照抄调用AddMessonScreen 那个。
Print String 节点,它们是两个完全不同的东西