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 绘制

相关推荐
REDcker1 小时前
有限状态机与状态模式详解 FSM建模Java状态模式与C++表驱动模板实践
java·c++·状态模式
basketball6162 小时前
C++ 构造函数完全指南:从入门到进阶
java·开发语言·c++
想唱rap3 小时前
IO多路转接之poll
服务器·开发语言·数据库·c++
落羽的落羽4 小时前
【算法札记】练习 | Week4
linux·服务器·数据结构·c++·人工智能·算法·动态规划
goodesocket4 小时前
芯片HAST测试:通电工作下如何精准模拟极端环境挑战?
c++
特种加菲猫5 小时前
从零开始手撕AVL树:详解插入、平衡因子更新与四种旋转
开发语言·c++
萑澈5 小时前
算法竞赛入门:C++ STL核心用法与时空复杂度速查手册
数据结构·c++·算法·stl
江屿风5 小时前
C++OJ题经验总结(竞赛)1
开发语言·c++·笔记·算法
运筹vivo@6 小时前
LeetCode 2405. 子字符串的最优划分
c++·算法·leetcode·职场和发展·哈希表
有点。6 小时前
C++(枚举法一练习题)
开发语言·c++·算法