Verse Wiki — 写给蓝图作者的 Verse 手册
拓展 · EXTRA

@editable 引用:把关卡里的对象接进代码

蓝图里勾一下 Instance Editable,再在 Details 面板拖一个 Actor 进去,代码就拿到了关卡里的对象。Verse 用 @editable 做同一件事,但多了几条规矩:默认值必须给、数组插槽怎么用、能不能引用你自己写的类,以及重命名字段会踩的雷。

一、Object Reference 变量 ↔ @editable 字段

这两件事是逐字对应的:

蓝图 Verse 差异
变量面板新建变量,类型选某个 Actor 类的 Object Reference TriggerButton:button_device 类型写法不同,含义一样:一个「指向关卡里某个对象」的字段
勾上 Instance Editable(那只眼睛) 字段上方独占一行的 @editable 蓝图是勾选框,Verse 是属性;两者都只是「让它出现在面板上」
默认值是 None = button_device{},必须写 Verse 不接受「空着」这个状态;漏写默认值直接 Compile 报红
Details 面板下拉框里挑一个关卡 Actor 同一个 Details 面板,拖进这个插槽 完全一致,这一步没有代码替代品

最需要适应的是第三行。蓝图里对象引用天然可以是 None,于是你养成了「用之前 Is Valid 一下」的肌肉记忆;Verse 把这条路堵死了——字段必须初始化成一个空原型,类型系统里不存在「这里可能是空的」。

但要说清楚一件事:这不等于「面板不连线也没事」。空原型只是让代码能编译,它不是关卡里那个真实对象。面板忘了拖线,进游戏碰它就是运行时错误。Verse 消灭的是「忘了判空」这类失误,没消灭「忘了配置」——后者永远是人的责任,蓝图那边也一样。

二、数组插槽:一次拖一批

蓝图里你会把变量类型改成 Array of Actor Reference,面板上就出现一个可以 + 添加元素的列表。Verse 同理:

notifier_device.verse
using { /Fortnite.com/Devices }
using { /UnrealEngine.com/Temporary/Diagnostics }

# 被通知方:暴露一个 public 函数当「收件口」
siren_device := class(creative_device):

    OnNotified<public>():void =
        Print("收到广播,警笛拉响!")

# 通知方:面板上拖进一批警笛,广播时挨个点名
notifier_device := class(creative_device):

    @editable
    Listeners:[]siren_device = array{}

    Broadcast<public>():void =
        for (L : Listeners):
            L.OnNotified()

读图翻译:[]siren_device 就是「一个装 siren 设备引用的数组」,默认值是空数组 array{};进编辑器后在面板上把关卡里的每台警笛拖进这个列表。Broadcast 用一个 ForEach 遍历列表,挨个调用它们暴露出来的 OnNotified

这是最直白的「一对多」做法,和第 25 课主课里的 event(t) 是两条不同的路:数组是点名式(通知方认识每一个听众,顺序可控),事件是广播式(发布方谁也不认识)。两者的取舍:

方式 耦合度 适合场景
@editable 单个引用,直接调它的 <public> 函数 高:甲必须认识乙 一对一、关系固定的两个对象
@editable 数组,ForEach 点名 中:名单在面板上,顺序可控 听众数量固定、需要确定顺序
共享 event(t),Signal / Subscribe 低:发布方不认识任何人 跨模块解耦、听众会增删

经验法则和你在蓝图里的一样:能用事件解耦就用事件;只有当你确实需要「按面板上的顺序逐个通知」或「运行时读得到这份名单」时,数组插槽才更合适。

三、引用你自己写的类

@editable 不只能引用原生设备,也能引用你自己写的 Verse 类——上面那个 Listeners:[]siren_device 就是例子,主课里 gate_device 引用 starter_device 也是。这相当于蓝图里把变量类型选成你自己那个 BP_Siren 类。

两条附加规则值得记住:

四、面板与代码之间的两个雷

雷一:改了代码,面板没变化。新加的 @editable 字段不会自己出现——要先把 Verse 代码重新构建 / 推送到编辑器。这一步相当于蓝图里点 Compile:不点,面板不会刷新。

雷二:重命名字段可能让已配置的引用丢失。面板上的配置是按字段名存的,改名之后旧配置可能对不上,表现为「面板上那一格突然空了」。蓝图里改变量名有重定向机制兜着,Verse 这边没有同等保障,所以改名之后务必回编辑器逐个检查插槽。这两条合起来,就是「代码全对、进游戏就炸」这类事故最常见的两个上游原因。

下面这个字段为什么 Compile 不过?@editable 换行后写 Door:barrier_device

来源

本文整理自 Epic 官方文档与开发者论坛: