蓝图 ↔ Verse 术语对照表
你知道自己要什么,只是不知道它在 Verse 里叫什么。这一页是全站查得最勤的一张表:先按领域给出「蓝图 → Verse」的六组对照,再给一份按字母排的「Verse → 蓝图」反查表,每一行都带一句差异说明和课号。当词典用,随查随走。
怎么用这张表
这一页有两个方向。从蓝图出发——你脑子里已经有那个节点、那个面板、那个资产类型,只想知道它在 Verse 里写成什么样,那就往下看第一到第六节,按领域分好组了。从 Verse 出发——你在文档、报错或者别人的代码里撞见一个眼生的词,想知道它对应你熟悉的哪个蓝图概念,直接跳到最后一节的反查表,按字母序排好了。
三句话说清怎么读:
- 前两列负责「写得出来」:左边是你在蓝图里的叫法,右边是 Verse 里的写法,照抄就能编译。
- 第三列负责「不踩坑」:很多词看着一一对应,行为却不一样(Boolean →
logic只是改名,但它不能直接当if的条件)。第一次用某个词,请把这一列读完。 - 第四列负责「弄明白」:查到了还想知道为什么,顺着课号跳过去。
口径说明:凡涉及 UE6 与 Scene Graph 的行,状态在对应小节的开头写清楚了。已经发生的事直陈,已承诺未交付的写明「尚未发布」,尚未公布的写明「尚未公布」。
一、类型与容器
你在变量面板的 Variable Type 下拉里能选到的那些东西,以及右键新建的那几种资产。
| 蓝图里的叫法 | Verse 里的写法 | 说明 | 在第几课 |
|---|---|---|---|
| Blueprint Class(蓝图类资产) | my_class := class: |
不是资产,是 .verse 文件里的一段声明,没有缩略图也没有资产路径。同样单继承、同样能实现多个接口。 |
第 20 课 |
| Child Blueprint Class(派生子类) | my_child := class(my_base): |
父类写在圆括号里。只能有一个父类,重写继承来的成员必须挂 <override>。 |
第 20 课 |
| Structure(结构体资产) | point := struct: |
同样是值语义(整包复制)。但 Verse 的 struct 里不能放 var 字段、也不能写方法,比蓝图结构体更「纯」。 |
第 21 课 |
| Enumeration(枚举资产) | suit := enum{Clubs, Hearts} |
背后不藏整数,不能转成数字或文字、也不能比大小。分头处理交给 case。 |
第 11 课 |
| Blueprint Interface(BPI) | rideable := interface: |
概念完全一致。实现方每个方法都要挂 <override>;没有蓝图那种「Message 调用 vs 直接调用」的分裂。 |
第 21 课 |
| Integer | int |
只是改了名。冷知识:整数 ÷ 整数得到的不是整数,是精确分数类型 rational,要用 Floor / Ceil 收回整数。 |
第 9 课 |
| Float | float |
字面量必须带小数点(写 1.0,不能写 1)。int 与 float 不会像蓝图那样自动互转,混着算直接报错。 |
第 9 课 |
| Boolean | logic |
改了名,而且用法不同:它不能直接当 if 的条件,要写 if (IsOpen?)——那个问号把「真 / 假」翻译成「走得通 / 走不通」。 |
第 11 课 |
| String | string |
双引号包起来,插值写 "HP: {Hp}"。底层是一串 char 排成的数组,所以数组那套(长度、按序号取、切片)对它照样管用。 |
第 10 课 |
| Text(可本地化文本) | message(由 <localizes> 产出) |
Verse 没有把本地化做成一种「变量类型」:你写一个挂 <localizes> 的常量或函数,它算出来的才是 message,UI 需要的就是这个类型。 |
第 22 课 |
| Name(FName,用于高速比对) | 没有对应物 | UE 的 String / Text / Name 三分在 Verse 里不存在。需要「一组固定标识」时正确做法是用 enum,不是拿字符串当标识。 |
第 11 课 |
| Array(数组容器) | []int / array{1, 2, 3} |
Verse 的数组是不可变的值,「改数组」其实是整包换成一个新的,没有 Add / Push。按序号取是可失败的:if (X := A[0]):,越界不会崩游戏。 |
第 16 课 |
| Map(映射容器) | [string]int / map{"k" => 1} |
查和写都可能走不通,连写入都得包在 if 里。能当键的类型必须属于「可比较」那一类。没有 Remove,删只能重建。 |
第 17 课 |
| Set(集合容器) | 没有内建对应物 | Verse 不提供集合类型。惯用替代是 [t]logic(即 map(t, logic)),只用键、把值当占位;去重这件事得你自己维持。 |
第 17 课 |
| Object Reference(对象引用引脚) | 直接写类型名,如 my_door |
没有单独的「引用类型」写法——类的实例天生就是引用语义,传的是同一个实例,不是拷贝。 | 第 20 课 |
| 「这个引用可能为空」/ Accessed None | ?my_door(option) |
「可能没有」被写进类型里,取值用 X? 并放进 if。运行时的 Accessed None 崩溃在 Verse 里不存在,编译期就逼你处理。 |
第 18 课 |
| Cast To …(以及那根 Cast Failed 引脚) | if (P := player[Agent]): |
方括号就是「这一步可能走不通」的记号。Cast 失败不报错、不崩,只是安静走进 else——和那根红色引脚是一回事。 |
第 12 课 |
| 函数的多个输出引脚 | tuple(float, float) |
蓝图靠多个 Return 引脚交出好几个值,Verse 把它们捆成一个元组返回。取第几个用圆括号 R(0),序号必须写死。 |
第 18 课 |
| Vector / Rotator / Transform | vector3 / rotation / transform |
由 /UnrealEngine.com/Temporary/SpatialMath 提供,用之前要 using 把它请进来。路径里的 Temporary 是提醒你:这套 API 以后会搬家。 |
第 7 课 |
这张表里最该记住的四行是 Boolean、Text/Name、Set 和 Object Reference:前两个是「改了名 + 行为不同」,第三个是「干脆没有」,第四个是「概念被折进类型系统里了」。剩下的基本可以直译。
二、变量与数据
变量面板本身:新建、读、写、暴露、权限。这一组对应关系最整齐,但默认值反了过来。
| 蓝图里的叫法 | Verse 里的写法 | 说明 | 在第几课 |
|---|---|---|---|
| 变量面板(My Blueprint › Variables) | 类里缩进一级的字段声明 | 没有面板。声明写在哪一级缩进,就属于哪个作用域——「这个变量属于这个类」由缩进直接表达。 | 第 8 课 |
| Get 节点 | 直接写名字 | 读一个值不需要任何节点,写出名字就是读它。 | 第 8 课 |
| Set 节点 | set Health = 80 |
set 是必须的关键字。漏掉它,单独一个 = 会被当成「判断相等」,报出一句新手看不懂的错。复合赋值有 += -= *=。 |
第 8 课 |
| Default Value(默认值那一栏) | 声明处的 = 100 |
函数里、模块层的声明必须当场给初值;类的字段可以不给,那样造实例时就成了必填项。 | 第 20 课 |
| Instance Editable(那只小眼睛) | @editable |
把字段暴露到 Details 面板,进关卡后改数值、连引用都不用重新编译。前提:字段得有默认值。 | 第 25 课 |
| Expose on Spawn(生成时暴露) | 原型语法 my_class{Field := 3} |
Verse 没有 new。造实例时在花括号里把没默认值的字段填上——这就是「生成时传参」。 |
第 20 课 |
| Private / Protected / Public(权限下拉) | <private> <protected> <public> <internal> |
默认档位不是 public,而是 <internal>(同模块可见)。跨文件夹用得上的东西,模块和成员都要挂 <public>。 |
第 22 课 |
| 「读公开、写受限」(蓝图做不到) | var<protected> Ammo<public>:int = 0 |
Verse 能把「谁能读」和「谁能改」分开标:外面随便读,只有自己人能 set。蓝图的权限下拉只有一档。 |
第 22 课 |
| Local Variable(函数内局部变量) | 函数体里的 var Count:int = 0 |
局部的也默认不可变,不写 var 就是局部常量。作用域跟着缩进走,出了缩进就没了。 |
第 8 课 |
| Const(蓝图变量做不到) | 什么都不写 | Verse 没有 const 关键字,因为「不可变」是默认待遇。反过来,「可变」才要申请一个 var。 |
第 8 课 |
| 函数参数的 By Ref 勾选 | 没有对应物 | 传进来的参数一律只读,想改先拷进一个局部 var。要把结果送回去,就正经返回一个值。 |
第 19 课 |
| Variable Category / Tooltip / 变量分组 | 没有语言级对应物 | 靠注释(# 与 <# … #>)和文件/模块划分来组织,不是面板上的元数据。 |
第 7 课 |
命名习惯 BP_MyDoor / bIsOpen |
类型名 my_door,成员名 IsOpen |
Verse 的分工是:类型名(class / struct / enum / interface)用 snake_case,值与函数用 PascalCase。没有 b 前缀那一套。 |
第 4 课 |
最后要盯一眼的是 Const 那一行。蓝图里没有「不可变变量」这个概念,所有变量都能接 Set;Verse 把默认值反了过来。这不是刁难——别人打开你的代码,一眼就能看出哪些值是死的、哪些是活的。
三、流程控制
执行线上的那些节点。这一组差异最大,因为 Verse 把「失败」当成一等公民:很多蓝图里靠 Boolean 和 Is Valid 解决的问题,在这里换了一套机制。
| 蓝图里的叫法 | Verse 里的写法 | 说明 | 在第几课 |
|---|---|---|---|
| Event BeginPlay | OnBegin<override>()<suspends>:void = |
它自带 <suspends>,可以在里面等几秒、等事件,是一根能挂起的长线,通常直接挂一整个游戏循环。BeginPlay 做不到这一点。 |
第 6 课 |
| Event EndPlay | OnEnd<override>():void = |
体验结束时跑。官方提醒:别指望在 OnEnd 里 spawn 出去的线还有机会跑完。 |
第 6 课 |
| Event Tick | 没有每帧回调;用 loop + Sleep(0.0) |
Verse 不给你一个 Tick 事件。要「每帧做一次」就自己写一个循环,每轮 Sleep(0.0) 正好等一帧。 |
第 23 课 |
| Branch(True / False 两条线) | if (条件): … else: |
Verse 的 if 收的不是 Boolean,是「这一步走不走得通」。Cast 失败、数组越界、查不到键,全都走同一个 else。 |
第 12 课 |
| Branch 的 Condition 引脚接一个 Boolean | if (IsOpen?): |
裸写 if (IsOpen) 编译不过。后缀问号把 logic 翻译成「走得通 / 走不通」。 |
第 11 课 |
| Select 节点(按条件二选一) | Max := if (A > B) then A else B |
if 本身就是表达式,直接吐值,不用另找一个三元运算符。 |
第 12 课 |
| Sequence 节点 | 顺序写下去 | 没有对应节点。缩进在同一级的几行,本来就是从上到下依次执行——白色执行线的本质就是顺序。 | 第 5 课 |
| ForEach Loop | for (X : Items): |
整个 for 跑完会攒出一个新数组,天生能「边跑边收集结果」。 |
第 14 课 |
| ForEach Loop with Index | for (I -> X : Items): |
序号从 0 起。箭头别和 map 的 => 搞混:建表用 =>,遍历读出用 ->。 |
第 14 课 |
| For Loop(数字范围) | for (I := 0..9): |
范围含两端,和 ForEach 是同一个关键字——Verse 把蓝图的两种循环合并成了一个。 | 第 14 课 |
| Loop Body 里的筛选(蓝图要套一个 Branch) | for (X : Items, X > 0): |
逗号后面直接写过滤条件,某一轮不通过就只跳过那一轮。这就是 Verse 版的 continue。 | 第 14 课 |
| While Loop | loop: 配 break |
Verse 没有 while,也没有 continue。条件搬进循环体,用 if (…): break 跳出。break 只属于 loop,for 里不能用。 |
第 15 课 |
| Delay(带小钟表的 latent 节点) | Sleep(1.0) |
只等自己这条线,游戏照跑。调用它的函数必须挂 <suspends>,因此它不能塞进 if 的条件里。 |
第 23 课 |
| Retriggerable Delay | 没有对应节点;用 race 重启计时 |
惯用法是让「计时」和「重置信号」赛跑,信号一来就整条重开。 | 第 24 课 |
| Is Valid / Is Valid? | if (D := MaybeDoor?): |
「可能为空」不靠运行时检查,而是写进类型(?t)。编译器会逼你处理,所以 Accessed None 这种崩溃在 Verse 里不存在。 |
第 18 课 |
| Switch on Enum | case (Phase): |
分支必须覆盖枚举的全部取值,或写一条 _ => 兜底,否则编译不过——漏了哪一项编译器会点名。 |
第 11 课 |
| Switch on Int / Switch on String | case 也能按字面量分支 |
整数、字符串这类没法穷尽的类型,必须留一条 _ => 兜底分支。 |
第 11 课 |
| Return Node | 隐式返回(函数体最后一个表达式) | 大多数时候什么都不用写。想提前退出才写 return;但在挂了 <decides> 的可失败函数体内禁止 return。 |
第 19 课 |
| Do Once | 没有内建节点;用一个 var 守门 |
惯用法是 if (not Done?): set Done = true; …,或者用一次性的事件等待代替。 |
第 12 课 |
| Flip Flop | set Flag = if (Flag?) then false else true |
没有取反运算符可用:not 在 Verse 里是「让一步失败变成通过」,不产出 logic 值,不能拿来翻转变量。 |
第 11 课 |
| Gate / MultiGate | 没有内建节点 | 用 var 记状态自己实现;要「几条线里谁先到听谁的」,那是 race 的活。 |
第 24 课 |
| Print String | Print("...") |
来自 /UnrealEngine.com/Temporary/Diagnostics,用之前要 using。插值直接写 Print("HP: {Hp}")。 |
第 6 课 |
| 「执行线走完这段之后一定要做的收尾」 | defer: |
蓝图里没有对应节点,只能每个出口都手工接一遍。defer 登记一次,从哪个出口离开都会补跑。 |
第 15 课 |
这一组有两件事是蓝图里根本没有的。一是失败:蓝图的 Branch 只有 True / False 两条线,Verse 的 if 还能承接「这一步没走通」,于是 Cast、取下标、查表全都归到同一套流程里。二是同时跑几条线:蓝图要做「一边倒计时一边等玩家踩板」得靠 Tick 手工拼,Verse 把 sync / race / rush / branch 做进了语言本身。
四、函数与事件
代码怎么被组织、怎么被触发。Event Dispatcher 那几行是迁移时最先用得上的。
| 蓝图里的叫法 | Verse 里的写法 | 说明 | 在第几课 |
|---|---|---|---|
| Function(蓝图函数) | Add(A:int, B:int):int = A + B |
参数表、返回类型、函数体一行写完。最后算出的值自动就是返回值。 | 第 19 课 |
| 「这个函数可能失败」(蓝图没有) | IsBig(X:int)<transacts><decides>:void = |
挂了 <decides> 的函数调用时用方括号 IsBig[200],且只能在允许失败的地方调。它必须与 <transacts> 成对出现。 |
第 22 课 |
| 函数的默认参数值 | Award(?Points:int = 1):void = |
名字前加 ? 就是命名可选参数,调用写 Award(?Points := 10)。位置参数没有默认值这一说。 |
第 19 课 |
| Pure 节点(绿色、没有执行引脚) | 效果说明符 <computes> / <converges> |
蓝图靠勾一个 Pure 复选框,Verse 靠在签名上申报「效果」。区别是 Verse 会检查你申报得对不对,申报了纯就不许偷偷写数据。 | 第 22 课 |
| Macro(蓝图宏) | 没有对应物 | 宏存在的理由之一是节点图不方便复用执行线。Verse 里写个普通函数就够了。 | 第 19 课 |
| Blueprint Function Library | 模块层的 <public> 函数 |
不需要专门建一个「库」资产。项目里每个文件夹自动是一个模块,函数挂上 <public> 别人就能用。 |
第 7 课 |
| Custom Event(自定义事件) | 类的一个普通方法 | Verse 里「事件」和「函数」是两个概念。蓝图的自定义事件,九成场合翻译过来就是一个方法。 | 第 25 课 |
| Event Dispatcher(事件分发器) | MyEvent : event(int) = event(int){} |
事件在 Verse 里是一等值:能当字段、当参数传、放进数组。蓝图的分发器只能挂在类上。 | 第 25 课 |
| Call(调用分发器,广播) | MyEvent.Signal(Payload) |
一样是「广播一声」,可以捎带一份数据。 | 第 25 课 |
| Bind Event(绑定) | Button.InteractedWithEvent.Subscribe(OnPressed) |
回调参数必须和事件递来的数据对得上。只绑一次——重复绑会叠加,按一下触发好几遍。 | 第 25 课 |
| Unbind Event | Handle.Cancel() |
Subscribe 会回一个 cancelable 把手,收着它才解得掉。 |
第 25 课 |
| 「在这里停下,等这个事件」(蓝图没有) | MyEvent.Await() |
蓝图的事件只能「另起一条执行线」,没法在一个函数中间挂起等它。Await() 让代码停在原地等,可读性完全不同。 |
第 23 课 |
| Implements Interface + Interface Call | my_class := class(my_iface): + 方法挂 <override> |
没有「Message 调用 vs 直接调用」的分裂——只有一种调法,编译期就保证对方实现了。 | 第 21 课 |
| 父类函数的 Override 下拉 | <override> |
重写继承来的成员必须挂它,忘了就报错。调父类原版写 (super:)Method()。 |
第 20 课 |
| Latent 节点 / Async Action | 挂 <suspends> 的函数 |
蓝图的异步是「某些节点自带的特殊能力」,Verse 的异步是签名上的一个标签,任何函数都能申请。 | 第 23 课 |
| 「同时跑好几条线」(蓝图要靠 Tick 手拼) | sync / race / rush / branch / spawn |
并发是语言内建的表达式,不是插件也不是节点。前四个只能在会等待的上下文里用,spawn 是唯一能在同步代码里用的。 |
第 24 课 |
五、引擎对象与框架 · 今天在 UEFN
这一组必须先说清状态,否则查表会查出误会。
今天(2026 年 8 月):Verse 唯一能真正跑起来的地方是 UEFN。它自 2023 年 3 月起就在 UEFN 生产环境运行至今。UEFN 里「关卡里的那个东西」叫 creative_device,你写的类从它继承,再从内容浏览器拖进关卡才会真正运行。
| 蓝图里的叫法 | Verse 里的写法 | 说明 | 在第几课 |
|---|---|---|---|
| Actor(能放进关卡的东西) | my_device := class(creative_device): |
今天的做法。拖几份进关卡就有几个实例,每份各跑各的代码。 | 第 6 课 |
| 把蓝图拖进关卡 | Build Verse Code 之后,从内容浏览器把设备拖进关卡 | 编译通过≠会运行。代码全写对但忘了拖进关卡,是新手前两大坑之一。 | 第 6 课 |
| Details 面板 | 用 @editable 暴露出来的字段 |
面板是代码的镜子,不是另一份数据。代码里没标 @editable,面板上就没有那一栏。 |
第 25 课 |
| Level Blueprint(关卡蓝图) | 没有对应物:做一台设备放进关卡 | Verse 没有「关卡级脚本」这个特殊容器。好处是设备能复制、能复用、能带进别的地图。 | 第 6 课 |
| World Outliner | UEFN 的 Outliner(编辑器工具) | 它是工具,不是语言概念。Verse 代码看不到 Outliner,只能看到面板上连给它的那些引用。 | 第 6 课 |
| Spawn Actor from Class | 惯用法:先把设备摆进关卡,再用代码启用 | UEFN 今天不能凭空生成任意设备。这是当前工具的限制,不是语言的限制。 | 第 25 课 |
| Get All Actors of Class | 今天没有等价写法 | 拿到别的设备只能靠 @editable 在面板上把引用连进来。代码全对、面板忘了连线,是另一个大坑。 |
第 25 课 |
| Pawn / Character | fort_character(Agent.GetFortCharacter[]) |
方括号说明这一步可能走不通(玩家可能已经淘汰了),必须包进 if。 |
第 25 课 |
| Instigator 引脚 / Player Controller | agent 与 player |
agent 是「能触发行为的家伙」这个抽象,player 是更具体的真人玩家。设备事件递给你的多半是 agent,要转成 player 得 if (P := player[Agent])。 |
第 25 课 |
| GameMode / GameState / PlayerState | 没有语言级对应物 | 在 UEFN 里这些职责由 Fortnite 的玩法框架和各种设备承担,不是你在 Verse 里定义的类。 | 第 25 课 |
| SaveGame / Save Game Object | 模块层的 weak_map(player, t) + <persistable> |
「放在类的外面」这个位置本身就是存档开关。数据每个玩家一份,退出重进还在。 | 第 28 课 |
| GameInstance(跨关卡携带数据) | 模块层变量;跨对局则用 <persistable> |
没有 GameInstance 这个对象。「活得比一局久」的数据要么放模块层,要么走持久化那一套。 | 第 28 课 |
| Actor Component / Scene Component | 今天的 UEFN 设备写法里没有直接对应物 | 组件模型是 UE6 的 Scene Graph 才引入的,见下一节。今天想复用行为,靠继承或把逻辑抽成模块层函数。 | 第 20 课 |
六、引擎对象与框架 · UE6 的方向:Scene Graph
状态,一次说清:UE6 把 UE5 与 UEFN 合并为一个引擎,Early Access 目标是 2027 年底。Scene Graph 是 UE6 的新玩法框架,从零基于 Verse 构建,用 entity(实体)装 component(组件);它目前在 UEFN 中以 Beta 提供,Epic 官方文档明确写着「谨慎用于正式发布」。
同时要记住三条,别被过期文章带偏:Actor 与 Blueprint 在 UE6 Early Access 及早期版本中完整支持,弃用要等 Scene Graph 足够成熟,时间未定;Epic 已承诺在弃用前提供转换工具,但尚未发布;Verse 将获得自己的可视化脚本层(社区称之为 Visual Verse),Epic 尚未公布形态。
| 蓝图里的叫法 | Verse 里的写法 | 说明 | 在第几课 |
|---|---|---|---|
| Actor | entity |
Actor 是一棵继承树的根,你靠「派生子类」加功能;entity 是一个几乎空的容器,你靠「装组件」加功能。这是换模型,不只是改名。 | 第 26 课 |
| Actor Component / Scene Component | my_comp := class<final_super>(component): |
名字一样,分工不一样:在 Scene Graph 里,组件是唯一放行为和数据的地方。<final_super> 是官方要求,少了就加不到 entity 上。 |
第 27 课 |
| Add Component(把组件挂到 Actor 上) | Entity.AddComponents(...) |
每个 entity 上同一类组件只能有一个。 | 第 27 课 |
| Get Component by Class | if (M := Entity.GetComponent[mesh_component]): |
方括号说明可能走不通——这个 entity 上未必装了那种组件。 | 第 27 课 |
组件里的 GetOwner() |
Entity(组件的一个数据成员) |
组件天生知道自己挂在哪个 entity 上,直接写 Entity 就行。 |
第 27 课 |
| Event BeginPlay(在组件上) | OnBeginSimulation<override>():void = |
组件有一串生命周期函数(加入场景 / 开始模拟 / 结束模拟 / 即将移出场景),重写你需要的那个。 | 第 27 课 |
| 「组件的长命异步逻辑」 | OnSimulate<override>()<suspends>:void= |
要在组件里挂一整个循环、等事件、等时间,写在这个函数里。 | 第 27 课 |
| Event Tick(在组件上) | TickEvents.PrePhysics / TickEvents.PostPhysics |
组件上有一个 TickEvents 成员,把回调挂上去就能拿到每帧的时机。 |
第 27 课 |
| Blueprint 预制资产 / 打包好的一组 Actor | prefab(继承 entity 的类) |
官方说法:在 Scene Graph 里,一个继承 entity 的类就叫 prefab。改 prefab,所有实例跟着变。 | 第 26 课 |
| Attach To / Detach(父子挂接) | AddEntities() / RemoveFromParent() / GetParent() |
entity 的层级不只是「摆放关系」,它就是数据结构本身:组件靠它找到彼此。 | 第 26 课 |
| Actor Tag / Component Tag | AddTag() / ContainsTag() / RemoveTag() |
entity 自带一套标签接口,可以按标签查、按标签删。 | 第 26 课 |
| 沿着层级广播一个通知 | SendUp() / SendDown() |
把一个场景事件顺着 entity 树往上或往下送,由沿途组件的 OnReceive() 接。 |
第 26 课 |
| @editable 在组件上 | @editable(与设备写法一致) |
组件的字段一样能用 @editable 暴露到面板,这一点从设备迁到组件不用重新学。 |
第 27 课 |
本节的 API 名称取自 Epic 官方 Verse API 文档的 /Verse.org/SceneGraph 模块与 Scene Graph 教程页。Scene Graph 仍在 Beta,签名与成员可能变动——写代码时以官方文档为准。
七、没有对应物的:那些不属于 Verse 的系统
查不到有两种。一种是「Verse 还没做」,另一种是「这压根不是 Verse 要管的事」。下面这几个属于第二种——它们是另外的系统,不在 Verse 要替代的范围内,以后也不会有一条「Verse 里怎么写 Timeline」的答案。
| 蓝图里的叫法 | Verse 里的写法 | 说明 | 在第几课 |
|---|---|---|---|
| Construction Script(构造脚本) | 没有对应物 | 它跑在编辑期:你在关卡里拖一下它就重算一遍。Verse 今天不参与编辑期构建,代码只在游戏运行时跑。 | 第 4 课 |
| Timeline(时间轴) | 没有对应物 | Timeline 是「曲线资产 + 播放器」的组合。Verse 有 Sleep 和循环,能手写插值,但没有曲线编辑器——曲线属于动画 / 序列系统。 |
第 15 课 |
| Animation Blueprint / AnimGraph / 状态机 | 没有对应物 | 状态机、混合空间、骨骼控制是一整套独立的动画系统。Verse 可以「告诉它切换状态」,但不会去替代它。 | 第 4 课 |
| Material Graph / Material Function | 没有对应物 | 材质节点最终编译成着色器跑在 GPU 上,和游戏逻辑不是同一种东西。 | 第 4 课 |
| Niagara(粒子特效) | 没有对应物 | 特效系统有自己的编辑器和运行模型。Verse 的角色是「在合适的时刻把它点着」。 | 第 4 课 |
| Reroute 节点 / Comment Box / 节点对齐 | 缩进与注释 | 节点图的排版工具在文本代码里没有意义。代码的「整洁」由缩进、命名和注释承担。 | 第 7 课 |
| Blueprint Nativization | 没有对应物 | 那是「把节点图转成 C++ 以提速」。Verse 本来就是文本代码,不需要这一步。 | 第 1 课 |
看清这条边界能省掉大量焦虑。「我的蓝图技能会不会作废」这个问题,在这张表面前有一半答案是现成的:你在材质、动画、特效、序列上积累的一切,和 Verse 完全无关,也就完全不受影响。Verse 要替代的只是「游戏逻辑」那一层——正好是前六节覆盖的范围。
八、反查:Verse → 蓝图
反过来用:你在文档、报错或者别人的代码里撞见一个词,想知道它对应你熟悉的哪个蓝图概念。按 Verse 里的写法排序,符号在前、字母在后。
| Verse 里的写法 | 一句话说明 | 对应的蓝图概念 | 在第几课 |
|---|---|---|---|
:= |
定义并初始化,只用于第一次;可以省略类型让编译器推断。 | 新建一个变量并填默认值 | 第 8 课 |
= |
判断相等的检定,不是赋值;Verse 里根本没有 ==。 |
Equal 节点 | 第 13 课 |
<> |
判断不相等;和 = 一样只能待在允许失败的地方。 |
Not Equal 节点 | 第 13 课 |
?(后缀查询) |
一物两用:接在 logic 后面问「是不是 true」,接在 option 后面把里面的值拆出来。两种都可能走不通。 |
Boolean 当条件用 / Is Valid | 第 11 课 |
[](方括号调用) |
「小心,这一步可能失败」的记号:取下标、查表、调 <decides> 函数、类型转换,全用它。 |
Cast Failed 那根引脚 | 第 12 课 |
{}(原型实例化) |
my_class{Field := 3} 造一个实例,花括号里把没默认值的字段填上。Verse 没有 new。 |
Spawn Actor from Class + Expose on Spawn | 第 20 课 |
@editable |
把字段暴露到 Details 面板,进关卡后改值不用重新编译;字段必须有默认值。 | Instance Editable 的小眼睛 | 第 25 课 |
agent |
「能触发行为的家伙」这个抽象,设备事件递给你的多半是它。 | Instigator 引脚 | 第 25 课 |
and / or / not |
组合「走得通 / 走不通」的三个词,没有 && || !;逗号也当 and 用。 |
AND / OR / NOT 节点 | 第 13 课 |
archetype(原型) |
Verse 造实例的方式,就是 my_class{…} 那个花括号写法。 |
在 Details 面板把必填项填好再 Spawn | 第 20 课 |
array |
一串同类型的值,不可变;「改数组」是整包换新。取下标可能失败。 | Array | 第 16 课 |
Await() |
停在原地等一个事件响,然后继续往下——只能在会等待的上下文里用。 | 蓝图没有:事件只能另起一条执行线 | 第 23 课 |
block |
把好几行打包成「一条线」,常用在 race / sync 的每条臂里。 |
Sequence 的一根输出 | 第 24 课 |
branch |
岔出一条线去跑,主线立刻继续;所在这段结束时岔线自动清场。 | 蓝图没有:有人管生命周期的 spawn | 第 24 课 |
break |
跳出 loop。只属于 loop,for 里不能用。 |
Break 节点 | 第 15 课 |
cancelable |
Subscribe 回给你的把手,调 Cancel() 解绑。 |
Unbind Event | 第 25 课 |
case |
按值分头走;枚举写全就不用兜底,否则要一条 _ =>。 |
Switch on Enum / Switch on Int | 第 11 课 |
class |
把数据(字段)和行为(方法)打包成能反复生成实例的东西;引用语义,单继承。 | Blueprint Class | 第 20 课 |
comparable |
「能判断相等」的那一类类型。为什么在意它?因为 map 的键必须出自这一类。 | 能不能当 Map 键的入场资格 | 第 17 课 |
component |
Scene Graph 里放行为和数据的地方;自定义组件写 class<final_super>(component)。Beta,以官方文档为准。 |
Actor Component | 第 27 课 |
<computes> / <varies> / <converges> |
三档「无副作用」承诺,只能挑一个;什么都不写默认是「不可回滚」。 | Pure 复选框(但编译器会检查) | 第 22 课 |
<concrete> |
全部字段都有默认值,因此能空手 my_class{} 造实例;自定义 @editable 类必备。 |
「这个类可以直接放进面板」 | 第 22 课 |
creative_device |
今天能放进 UEFN 关卡的类的基类,写 my_device := class(creative_device):。 |
Actor / Blueprint Actor | 第 6 课 |
<decides> |
把函数变成「可能走不通」的,调用时用方括号;必须与 <transacts> 成对出现。 |
蓝图没有:最接近的是 Cast 的双出口 | 第 22 课 |
defer |
「离开这段之前,最后一定补跑的一根线」;只要执行流经过它登记上就算数。 | 蓝图没有:得每个出口手工接一遍 | 第 15 课 |
entity |
Scene Graph 里的容器,本身几乎没有行为,靠装组件获得功能。Beta,以官方文档为准。 | Actor | 第 26 课 |
enum |
一组起好名字的选项;背后不藏整数,不能转数字或文字。 | Enumeration 资产 | 第 11 课 |
event(t) |
事件本体:Signal(X) 广播,Subscribe(F) 注册回调,Await() 挂起等它。 |
Event Dispatcher | 第 25 课 |
| expression(表达式) | Verse 里凡是写下的都会算出一个值,连 if 和 for 都吐值——这就是不用 Return 节点的原因。 |
蓝图的「执行节点 vs 数据引脚」之分被抹掉了 | 第 3 课 |
| failure context(失败上下文) | 允许放「可能走不通」的检定的地方:if 的条件、for 的括号、not / or 的操作数、<decides> 函数体、option{…}。 |
蓝图没有对应概念 | 第 12 课 |
<final> |
类不许被继承 / 成员不许被重写。 | 「别派生我」 | 第 22 课 |
<final_super> |
Scene Graph 的硬性要求:自定义组件必须直接派生自 component,不写就加不到 entity 上。以官方文档为准。 |
蓝图没有对应概念 | 第 27 课 |
float |
小数;字面量必须带小数点,不与 int 自动互转。 |
Float | 第 9 课 |
for |
逐个跑一遍,还能顺手加过滤条件;整个 for 跑完会攒出一个新数组。 |
ForEach Loop + For Loop 的合体 | 第 14 课 |
fort_character |
玩家在世界里的角色本体,用 Agent.GetFortCharacter[] 拿(可能失败)。 |
Character / Pawn | 第 25 课 |
if |
问的是「括号里这件事走不走得通」,不是「Boolean 是不是 true」;本身是表达式,能直接取值。 | Branch(外加 Select 与 Cast 的功能) | 第 12 课 |
| implicit return(隐式返回) | 函数体最后算出的值自动就是返回值;<decides> 函数体内禁止写 return。 |
Return Node(大多数时候不用写) | 第 19 课 |
int |
整数。整数 ÷ 整数得到的是精确分数 rational,要 Floor / Ceil 收回来。 |
Integer | 第 9 课 |
interface |
只列函数签名不写实现,谁答应谁补齐(每个都要 <override>)。一个类能同时答应好几个。 |
Blueprint Interface(BPI) | 第 21 课 |
<localizes> |
把插值字符串包装成 message,UI 文本要的就是这个类型。 |
Text(可本地化文本) | 第 22 课 |
logic |
true / false。当条件用要补个问号 Flag?。 |
Boolean | 第 11 课 |
loop |
自己绕回去、无条件重复的一根线;出来只能靠 break 或 return。同步 loop 里不歇一下会触发死循环错误。 |
条件恒为 True 的 While Loop | 第 15 课 |
map |
「键 → 值」的登记表;查和写都可能走不通,连写入都得包 if。 |
Map(TMap) | 第 17 课 |
message |
可本地化的文本类型,由挂 <localizes> 的常量或函数产出。 |
Text | 第 22 课 |
Mod[A, B] |
求余。Verse 没有 %,而且方括号提醒你这一步可能失败。 |
Modulo 节点 | 第 13 课 |
module |
一包能被别人依赖的代码。项目里每个文件夹自动是一个同名模块。 | 启用一个插件 / 引用另一个文件夹的资产 | 第 7 课 |
OnBegin / OnEnd |
设备的一头一尾。OnBegin 自带 <suspends>,可以挂一整个游戏循环。 |
Event BeginPlay / Event EndPlay | 第 6 课 |
option(?t) |
「可能装了东西、也可能是空」的盒子;false 是空,装东西用 option{42},取用 X?。 |
可能为空的对象引用 + Is Valid | 第 18 课 |
<override> |
重写继承来的成员,必加;调父类原版写 (super:)Method()。 |
函数的 Override 下拉 | 第 20 课 |
<persistable> |
「够格进存档」的资格:类须 <final> 且只放不可变字段。 |
SaveGame Object 的字段 | 第 28 课 |
player |
真人玩家,是 agent 更具体的一种;转换写 if (P := player[Agent])。 |
Cast to Player | 第 25 课 |
| prefab | 官方说法:Scene Graph 里一个继承 entity 的类就叫 prefab,可复用、可嵌套。Beta,以官方文档为准。 |
打包好的一组 Actor / 蓝图预制 | 第 26 课 |
Print |
往日志打一行,支持插值 Print("HP: {Hp}")。要先 using Diagnostics 模块。 |
Print String | 第 6 课 |
race |
几条线同时跑,谁先到算谁的,其余的在各自下一个等待点被剪断。「超时」的标准写法。 | 蓝图没有:得靠 Tick 手工拼 | 第 24 课 |
rational |
精确分数类型,整数 ÷ 整数的结果就是它。 | 蓝图没有:那里的除法直接给你 Float | 第 9 课 |
rush |
和 race 一样取最先跑完的结果,区别是落后的线不被剪断,继续跑完。 |
蓝图没有 | 第 24 课 |
Self |
方法里指「我这个实例」。 | Self 引脚 | 第 20 课 |
set |
给变量换个新值。少写 set,编译器会把你的「改值」当成「判等」。 |
Set 节点 | 第 8 课 |
| simulation update | 与 tick、帧同义,Verse 时间流的最小刻度;Sleep 的精度以它为底。 |
一帧 / 一次 Tick | 第 23 课 |
Sleep(x) |
让当前这条线原地等若干秒,只等它自己。Sleep(0.0) 正好等一帧。 |
Delay 节点 | 第 23 课 |
spawn{ Fn() } |
岔出一条新线,自己立刻往下走;是唯一能在同步代码里用的并发写法。 | 蓝图没有:最接近的是「另起一条执行线」 | 第 24 课 |
| speculative execution(投机执行) | 失败上下文的运行方式:先大胆试,整条检定走不通就把这期间的改动全部作废。 | 蓝图没有:Set 泼出去就收不回 | 第 12 课 |
string |
文字,双引号包起来;插值用花括号 "HP: {Hp}"。底层是 char 数组。 |
String | 第 10 课 |
struct |
一小包纯数据,值语义(整包复制);不能放 var 字段、不能写方法。 |
Structure 资产 | 第 21 课 |
Subscribe |
给事件挂回调,回一个 cancelable;只绑一次,重复绑会叠加触发。 |
Bind Event | 第 25 课 |
<suspends> |
函数的「异步执照」:体内可以有等待,能跨帧挂起。只能在同样会等待的上下文里直接调。 | Latent 节点(带小钟表那种) | 第 23 课 |
sync |
几条线一起跑,全部到齐才继续;结果按书写顺序打成一个 tuple。 | 蓝图没有 | 第 24 课 |
task |
spawn 岔出去那条线的把手,可以 Await() 等它跑完。它没有现成的 Cancel。 |
蓝图没有 | 第 24 课 |
<transacts> |
申报「我做的事全都能撤销」。失败上下文只放行「能反悔」的函数。 | 蓝图没有对应概念 | 第 22 课 |
tuple |
把固定几个、可以不同类型的值捆成一小包;取第几个用圆括号,序号必须写死。 | 函数的多个输出引脚 | 第 18 课 |
<unique> |
挂上之后每个实例都带一张「身份证」,能互相比较、能当 map 键——player 就是这么来的。 |
对象引用的「是不是同一个」 | 第 20 课 |
using { … } |
把某个模块里公开的东西请进当前文件;花括号不能省。 | 启用插件 / 添加模块依赖 | 第 7 课 |
var |
「这个值以后要改」的申请。不写 var 就是常量——这是 Verse 与蓝图最大的默认值差异。 |
蓝图变量默认就是可变的 | 第 8 课 |
weak_map |
map 的特殊亲戚:不能遍历、问不出总数。放在模块层、以玩家为键,就是存档。 |
SaveGame | 第 28 课 |
没查到?两种可能。要么它属于第七节那些「不归 Verse 管」的系统,要么它是 Scene Graph 的新词——那一组还在 Beta,名字和签名以 Epic 官方文档为准。