Unlua 官方案例

一.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(准确说是继承自 AActorALevelScriptActor),但在实际使用中,它更像一个关卡专属的"全局事件图表",而非一个能自由放置的普通 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 文件),并把返回的内容赋值给局部变量 ScreenScreen 模块是UnLua教程中封装的一个辅助工具,它的 Print 方法可以在游戏画面上 显示文字,类似UE蓝图中的 "Print String" 节点。注意:这个 Screen 并非UE引擎自带的API,而是教程专用的辅助模块。

人话:就是引入Unlua输出到屏幕的模块,这个不是自带的。

Lua 复制代码
local Screen = require "Tutorials.Screen"

这一行创建了一个UnLua (可以理解为一个"Lua脚本模板"),并将其赋值给局部变量 MUnLua.Class() 是UnLua提供的核心API,它会生成一个具备UE绑定能力的Lua表,后续我们可以向这个表添加方法(比如 Initialize),最后返回给UnLua使用。

这里 M 只是一个约定俗成的变量名(Module的首字母),你可以改成任何名字。

人话就是: 必须要的对象,统一开头。没这个类就没得玩了,它里面有大量unluaAPI。

UnLua.Class() 本身只是生成一个普通的Lua表 ,真正让它"有魔法"的是最后 return M 给UnLua框架 。UnLua拿到这个表之后,会把UE对象和这个表绑定在一起,然后表里的 InitializeReceiveTick 等方法才会被自动调用。所以确实可以理解为"固定开头模板",不写就没法绑定。

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 节点,它们是两个完全不同的东西

Screen.Print持久化 HUD 绘制

相关推荐
鲸渔2 小时前
【C++ 变量与常量】变量的定义、初始化、const 与 constexpr
java·开发语言·c++
John_ToDebug2 小时前
Chrome 首次启动引导页里触发 Pref 设置,为什么主进程收不到 IPC
c++·chrome
我头发多我先学2 小时前
C++ STL vector 原理到模拟实现
c++·算法
鲸渔2 小时前
【C++ 入门】第一个程序:Hello World 与基本语法规则
开发语言·c++·算法
EverestVIP2 小时前
C++ 仿函数(Functors)
c++
会编程的土豆2 小时前
【数据结构与算法】 时间复杂度计算
数据结构·c++·算法
John_ToDebug2 小时前
Chromium 页面类型与 IPC 通信机制深度解析
前端·c++·chrome
小年糕是糕手2 小时前
【35天从0开始备战蓝桥杯 -- Day9】
数据结构·数据库·c++·算法·蓝桥杯
山甫aa2 小时前
STL---常见数据结构总结
开发语言·数据结构·c++·学习