DreamGUI
诊断码

DUI3xxx · 语义

语法没错,但这棵树对不上:重复的 id、未知的类型。

本页由 scripts/diagnostics/sync.py 从插件的码表(EDreamUIDiagnosticCode)生成,卡片里的枚举名就是测试断言用的那个名字。

DUI3001

错误枚举名DuplicateNodeId

两个用了同一个 id 的节点。

怎么会出现:id 是节点的身份:它同时是 guid、类成员变量名、绑定的键和本地化键。比较不区分大小写,因为它最终变成一个 FName。重复的 id 永远不会被悄悄改成 OkBtn_1,那样会让你的绑定悄悄指向另一个节点。slot 和控件共用这个命名空间,所以两个同名的 slot、一个和控件同名的 slot 也是这个码;宿主里填充组件 slot 的 slot Detail { … } 不算。

Widget Root {
    Text Title { Text = "Settings" }
    Text title { Text = "Audio" }
}

怎么改:给其中一个改名;如果冲突来自一次改名,用 (was: …) 让下一次编译把引用迁移过去。

DUI3002

错误枚举名InvalidNodeId

一个不是标识符、以数字开头或者是关键字的 id。

怎么会出现:id 要能当 C++ 标识符:字母、数字和 _,不以数字开头(ASCII 以外的字符算字母,所以 id 可以是中文)。2ndPanel 会被拒绝,因为生成的类会把它声明成 _2ndPanel,照着文件里的名字写的绑定就全都对不上。class、style、resources、slot、for、each、in、was、use、timeline、external、ease 是关键字,不能当节点 id 或 slot 名;超过 FName 长度的 id 也报这个码。

Widget Root {
    Text 2ndLine { }
    Text external { }
}

怎么改:换一个以字母或 _ 开头、不是关键字的 id,比如 SecondLine。

DUI3003

错误枚举名UnknownNodeType

一个既不是标签、容器、别名、注册控件,也不是路径的节点类型。

怎么会出现:节点类型按顺序解析:内置标签(Text、Image 等)、布局容器(VerticalBox 等)、use … as 给出的组件别名、注册标签(Native.Button 等)、资产路径(以 / 开头)。都对不上就报这个码;对带作用域或命名空间的名字,消息会列出那里实际有哪些。

Widget Root {
    Txt Title { Text = "Settings" }
}

怎么改:修正拼写;组件先用 use "…" as Name 引进来,或者写它的完整资产路径。

DUI3004

错误枚举名UnknownStyle

一个指向这个文件看不到的样式的 : Name。

怎么会出现:节点的样式子句或者样式的基类,用了一个既没有在本文件声明、也没有被 use 带进来的样式名。样式可以写在戴它的节点下面,先后不影响。带命名空间的名字(nier.Label)如果命名空间本身没被声明,报的是 DUI3021 而不是这个码。

style Caption { FontSize = 14 }
Text Note : Captoin { Text = "Ready" }

怎么改:修正样式名,或者 use 声明了它的那个库。

DUI3005

错误枚举名DuplicateStyle

同一个文件里的两个同名样式。

怎么会出现:本地样式可以遮蔽导入的同名样式,但两个本地样式同名时,构建器和写回器可能对“一个节点到底拿到了哪些属性”得出不同的答案,所以第二个被拒绝。

style Caption { FontSize = 14 }
style Caption { FontSize = 12 }

Text Note : Caption { Text = "Ready" }

怎么改:合并成一个,或者改名其中一个;要在一个样式上做变体,用继承,比如 style Small : Caption。

DUI3006

错误枚举名UnknownBehaviourClass

一个指向控件无法携带的东西的 + Name。

怎么会出现:+ 后面的类名会依次加上插件的前缀去找(UIButton 和 Button 都能找到按钮行为),也可以写 /Script/Module.Class 全路径;找不到一个行为、布局容器或 layout-self 对象时报这个码。样式里的 + 行也一样。

Widget Confirm {
    + UIButon { TransitionType = None }
}

怎么改:修正类名,或者写出完整的 /Script/… 路径。

DUI3007

错误枚举名DuplicateSlotName_Retired

这个码已经退役、从不报出,两个同名 slot 现在报 DUI3001。

DUI3008

警告枚举名ShadowedLoopVariable

一个遮蔽了外层循环变量的循环变量(警告)。

怎么会出现:嵌套的 for / each 用了和外层一样的变量名。它只是警告,因为遮蔽本身改变不了构建出来的树。不过循环本来就不能嵌套:构建时内层循环会被 DUI5021 或 DUI5012 拒绝。

VerticalBox Groups {
    for Item in GetGroups() {
        VerticalBox Group {
            for Item in GetEntries() {
                Text Entry { Text <- Item.Name }
            }
        }
    }
}

怎么改:内层换一个变量名;更要紧的是把内层循环放进一个组件,由组件自己的文件去循环,列表经由它的 props 传进去。

DUI3009

错误枚举名ParentRefusedChild

一个不肯接受这个子节点的父节点:已经满了的内容控件,或者被填了两次的命名 slot。

怎么会出现:节点没问题,父节点也没问题,只是这一对不行。SizeBox、ScaleBox、SafeZone、Border 只放一个子节点;命名 slot 只放一个控件,同一个 slot 也不能填两次;嵌套成环同样被拒绝。挂接时多出来的子节点会被悄悄丢掉,没有这个码,你会得到一棵少了一截的树,而那一截明明就写在你的文件里。

SizeBox Box {
    Text A { Text = "One" }
    Text B { Text = "Two" }
}

怎么改:把几个子节点放进一个容器(比如 VerticalBox { … })再放进去;需要一个 slot 放多个控件时,在声明里给它一个布局容器。

DUI3010

错误枚举名RenameOldIdStillInUse

一个 (was: X),而 X 仍然是这个文件里某个节点的 id。

怎么会出现:你把节点从 X 改了名,又新建了一个叫 X 的节点。“把指向 X 的东西都搬过来”会把引用从一个确实存在、也需要它们的节点上搬走,所以拒绝;而且整个文件的迁移都不做,因为迁移了一半的文件比没迁移的更糟:下一次编译就不再从作者写下的样子出发了。

Widget Root {
    Text Title (was: Heading) { Text = "Settings" }
    Text Heading { Text = "Audio" }
}

怎么改:先给另一个节点改名,或者删掉 (was: Heading)。

DUI3011

错误枚举名DuplicateWasId

两个都声称 (was: X) 的节点。

怎么会出现:一个旧名字不能变成两个新名字,没有办法决定由谁继承 X 的引用,所以整个文件的迁移都不做。

Widget Root {
    Text Title (was: Heading) { }
    Text Subtitle (was: Heading) { }
}

怎么改:把子句留在要继承引用的那个节点上,删掉另一个。

DUI3012

错误枚举名SelfRename

一个写在节点 X 自己身上的 (was: X)。

怎么会出现:改名子句说的是节点以前叫什么,名字没变就没有可迁移的东西,几乎一定是笔误;整个文件的迁移都不做。

Text Title (was: Title) { Text = "Settings" }

怎么改:删掉这个 (was: …);如果是想改名,把新的 id 写在类型后面,旧的写进 (was: …)。

DUI3013

警告枚举名RenameGraphReferenceAmbiguous

一个同时是别的成员名字的旧 id,因此图表引用没有被迁移(警告)。

怎么会出现:Blueprint 图表里的引用按名字解析。如果旧名字同时是这个 Blueprint 自己声明的变量、父类的成员,或者某个函数里的局部变量,改写所有对它的引用就会悄悄改动与这个控件毫无关系的代码,所以图表这一路不做。绑定和动画轨道这两路没有歧义,照常迁移。

怎么改:手动把图表里的引用指向新名字,或者给另一个同名的东西改名。

DUI3014

错误枚举名DuplicateResource

两个同名的资源条目。

怎么会出现:条目会在多个 resources 块之间累积;一个名字声明了两次时,第一个处处生效,所以第二个被拒绝。

resources {
    Color Accent = #FF6600
    Color Accent = #E05A47
}

Text Note { Color = @Accent }

怎么改:删掉其中一个,或者给它改名。

DUI3015

错误枚举名StyleCycle

一个沿着基类链继承了自己的样式。

怎么会出现:style A : B,沿着基类往上走又回到了 A。这时什么都不应用,戴着这个样式的节点报这个码。

style Caption : Warning { FontSize = 14 }
style Warning : Caption { Color = #E05A47 }

Text Note : Warning { Text = "Unsaved changes" }

怎么改:断开这个环,让其中一个不再继承另一个。

DUI3016

错误枚举名DuplicateTimeline

两个同名的时间轴。

怎么会出现:时间轴的名字既是动画的显示名,也是一个类成员变量(编译器为每个动画声明一个,和 UMG 为 UWidgetAnimation 做的一样),两个同名就是一个谁也访问不到的变量,和两个同名样式一样被拒绝。

timeline Pulse external
timeline Pulse { duration = 0.6 }

Widget Root { }

怎么改:给其中一个改名。

DUI3017

错误枚举名DuplicateComponentAlias

两行给出同一个名字的 use … as。

怎么会出现:第一行处处生效,第二行被拒绝,免得一个类型名因为远处的某一行而悄悄换了意思。

use "UI/Components/Row.dui" as Row
use "UI/Components/NieR_Row.dui" as Row

Widget Root { }

怎么改:给第二个换一个名字。

DUI3018

错误枚举名AliasShadowsBuiltIn

一个与标签或容器同名的 use … as 名字。

怎么会出现:节点类型先问内置标签和布局容器,再问别名,所以叫 Text 或 VerticalBox 的别名永远写不出来:别名改变不了 Text 的意思。

use "UI/Components/Label.dui" as Text

Widget Root { }

怎么改:换一个不是标签或容器名的名字,比如 Label。

DUI3019

错误枚举名DuplicateProp

两行声明同一个名字的 props。

怎么会出现:一个名字只能是一个属性;第一行保留,第二行被拒绝。

props {
    Text   Label
    String Label
}

Widget Root { }

怎么改:删掉其中一行,或者给它改名。

DUI3020

错误枚举名DuplicateEvent

两个同名的 events 条目,或者一个条目里声明了两次的参数。

怎么会出现:每个事件都会变成一个事件分发器,所以名字必须唯一;同一个事件的参数名也必须唯一。

events {
    Picked(Number Index, Number Index)
    Closed
    Closed
}

Widget Root { }

怎么改:删掉重复的那个,或者给它改名。

DUI3021

错误枚举名UnknownNamespace

一个 ns 没有被任何 use … as ns 声明过的 ns.Name。

怎么会出现:样式、资源和组件别名可以带命名空间前缀(: nier.Label、@nier.Ink、nier.Row),这个前缀必须来自 use "…" as nier。这种情况只报这一个码,不会再报一条“没有这个样式”,把你引去找一个并不存在的拼写错误。

Text Note : nier.Label { Text = "Ready" }

怎么改:加上 use "UI/NieR_Common.dui" as nier,或者修正前缀的拼写。

DUI3022

错误枚举名MultipleDefaultSlots

一个文件里不止一个 slot … default。

怎么会出现:嵌套进来却没写 slot 名的内容只有一个去处。第一个保留默认的角色,这样已经按它编译过的宿主仍然一致。

Widget Root {
    slot Rows default
    slot Footer default
}

怎么改:只在一个 slot 上写 default。

DUI3023

警告枚举名DuplicateRowKey

一个 rows 表里第一个值生成了同一个 id 的两行(警告)。

怎么会出现:每一行的 id 来自它的第一个值(比如 Page_0__Row_City_Ruins),这样插入或调整行的顺序不会动到别的行的 id 和本地化键。两行的键生成了同一个 id,或者生成了文件里已经有的 id 时,后一行会在后面加上 _1 这样的序号,而这个序号连同它的本地化键会随着行的顺序移动,这恰恰是键列要避免的不稳定。

VerticalBox Menu {
    rows Text (Text) {
        "Audio"
        "Audio"
    }
}

怎么改:让各行的第一个值互不相同;需要按名字找到的行,写成单独的节点。

本页目录