形状语法在虚幻引擎的程序化内容生成框架中的常见用途是构建系统。 在本示例中,你将创建一个栅栏生成器。它可以使用语法沿样条线生成数个静态网格体,并在样条线控制点变动时随之修改网格体。
此示例使用Fab商城中的免费私人栅栏包(含破损分段)资产包。 但此示例可以使用你选择的任意静态网格体来创建。
先决条件
本操作指南所使用的术语和概念已在以下文档中有所讨论:
项目设置
在虚幻引擎中新建项目。
使用基本(Basic)关卡模板创建新关卡。 保存关卡。
打开编辑(Edit) > 插件(Plugins)并确认激活了以下插件:
程序化内容生成框架(PCG)
程序化内容生成框架(PCG)几何体脚本互操作
创建样条线
将PCG图表连接到一个PCG组件和一个样条线,它们包含在一个新的蓝图类中。 创建蓝图类的步骤如下:
在内容侧滑菜单或内容浏览器中点击右键,选择蓝图类(Blueprint Class)以创建一个新蓝图类。
将新蓝图类命名为FenceSpline。
在组件(Components)选项卡中添加一个工具样条线和一个PCG组件。
保存蓝图类。
PCG图表资产
PCG图表是栅栏生成器的基础,包含了用于沿样条线生成栅栏分段的指令。 新建PCG图表资产的步骤如下:
在内容侧滑菜单或内容浏览器中点击右键,找到PCG并选择PCG图表。
将新资产命名为PCG_FenceGen并按Enter键。
双击PCG_ForestGen打开PCG图表编辑器。
创建PCG语法
语法以字符串的形式存储在图表参数中。 由于将值存储在参数中,因此它可以通过参数重载(Parameter Overrides)来自定义关卡中每个栅栏生成器的实例。 之后,语法(Grammar)属性会被添加到样条线数据,并传递给细分样条线(Subdivide Spline)节点,从而沿着样条线分配点。
在PCG图表编辑器窗口中,将一个Get Spline Data节点添加到图表。
点击屏幕上方的按钮,打开图表设置(Graph Settings)以新建一个参数(Parameter)。 将新参数命名为Grammar并将其类型改为字符串(String)。
将Grammar的初始值设置为
A*。 这会让图表放置一个初始静态网格体,然后使用静态网格体填充样条线的剩余部分,直至填满所有空间。拖出Get Spline Data节点的输出引脚,创建一个Add Attribute节点。 在细节面板中,将输出目标(Output Target)改为
Grammar。为Grammar参数创建一个“Get”节点,并将其连接到Add Attribute节点的Attributes输入。
勾选接受不完整细分(Accept Incomplete Subdivision)复选框。
勾选以语法为属性(Grammar as Attribute)复选框并将语法属性(Grammar Attribute)设为
Grammar。
为语法分配网格体
你需要为语法中的每个符号都分配一个静态网格体,以便生成。 这要用到两个参数:模块信息(Module Info)和网格体信息(Mesh Info)。 模块信息包含一组符号。 网格体信息包含一组静态网格体。 此信息在稍后会以属性集的形式被传递到细分样条线(Subdivide Spline)节点。
选中细分样条线(Subdivide Spline)节点,勾选以模块信息为输入(Module Info as Input)。 这会为属性添加一个输入,它被用于将模块信息分配给语法符号。
在图表设置中新建一个参数,将其命名为Module Info。 将其类型改为PCG细分子模块(PCG Subdivision Submodule)并点击类型旁的下拉菜单,选择数组(Array)。 它将保存我们的符号信息。
点击+按钮,添加一个新的数组元素。再点击索引[0](Index [0])旁的箭头打开此条目。
将符号(Symbol)值设置为
A并勾选可缩放(Scalable)复选框。在图表设置中新建一个参数,将其命名为Mesh Info。 将其类型改为静态网格体(Static Mesh)并点击类型旁的下拉菜单,选择数组(Array)。 它将保存我们的静态网格体信息。
点击+按钮,在Mesh Info中添加一个新的数组元素。
打开索引[0](Index [0])旁的下拉菜单,选择Fence_17_DE静态网格体。
创建提取信息子图表
细分过程会为每个模块分配一个尺寸,并在边界中心放置一个枢轴点。 如果网格体在之后发生变化,或其枢轴点没有位于网格体中心,这就会造成问题。 此子图表会直接从所选网格体的边界上提取尺寸信息,并调整其枢轴点,使其位于网格体中心。
设置Input节点
在内容侧滑菜单或内容浏览器中新建一个PCG图表并将其命名为PCG_ExtractInfo。
点击Input节点,在细节面板中打开引脚(Pins)选项。 打开索引[0](Open Index [0])并将标记(Label)改为
Mesh Info。将允许的类型(Allowed Types)选项改为点或参数(Point or Param)。
将引脚状态(Pin Status)选项改为普通(Normal)。
将说明文本(Tooltip)改为
要提取信息的网格体列表(List of meshes to extract info from)。
提取网格体边界
打开图表设置并创建一个新的参数。 将其命名为Mesh Attribute Name并设置类型为Name。 将其初始值设置为
Mesh。拖出Input节点的输出引脚,创建一个Attribute Rename节点。
在细节面板中,将新属性名称(New Attribute Name)设为
Mesh。创建一个Get Mesh Attribute Name节点,将其连接到Attribute Rename节点的Attribute to Rename输入。
从Attribute Rename节点拖出引线,新建一个Bounds From Mesh节点。
点击新节点,将网格体属性(Mesh Attribute)值设置为
Mesh。拖出Attribute Rename的输出引脚,将其连接到Bounds From Mesh节点的Attribute输入。 图表会自动创建一个筛选器来创建恰当的输入。
按住ALT键并点击新筛选器节点的输出引脚,断开其连接。
从断开的筛选器节点拖出引线,创建一个Attribute Set To Point节点。 将该节点的输出连接到Bounds From Mesh的输入。 这可以让图表同时支持点和属性集数据类型。
点击“Bounds From Mesh”节点,将网格体属性(Mesh Attribute)选项设为
Mesh。
调整枢轴点
静态网格体上的枢轴点需要调整,才能在样条线上正确显示。首先,从Bounds From Mesh拖出引线,创建Multiply节点。
点击新节点,将Input Source 1的值设置为
$Extents.X。这将从边界数据中提取X范围。从In B输入拖出引线,创建Create Attribute节点。 将Double Value改为
2.0。再次点击Multiply节点,将Output Target值更改为
Size。 这将输出X值乘2后的结果,并将其存储在名为Size的属性中。从Multiply节点拖出引线,创建Copy Attributes节点。 再从Multiply的输出拖出引线,将其连接到新节点的Source输入。 此节点会从边界数据中提取X的范围,并将其存储在属性中以备在将来有需求时帮助进行缩放。
点击Copy Attributes,将Input Source设为
$Extents.Z。将Output Target设为
ExtentsZ。从Copy Attributes的输出拖出引线,再创建一个Multiply节点。 此节点将帮助把枢轴点移动到网格体的中心。
从In B输入拖出引线,创建Create Attribute节点。 将Double Value改为
-1.0。再次点击Multiply节点。 在细节面板中将Input Source 1的值设为
$LocalCenter。将Output Target的值设为
PivotOffset。
设置Output节点
点击Output节点,将其放在图表的末端。
在细节面板中打开引脚(Pins)选项。 打开索引[0]并将允许的类型(Allowed Types)改为属性集(Attribute Set)。
将引脚状态(Pin Status)选项改为普通(Normal)。
从Multiply节点的输出拖出引线,新建一个Point to Attribute Set节点。
将新节点的输出连接到Output节点的Out引脚。
保存完成的图表。
回到PCG_FenceGen图表编辑器窗口。 将你的PCG_ExtractInfo图表资产从内容侧滑菜单或内容浏览器拖放到视口中,并选择创建PCG_ExtractInfo子图表节点。
应用模块和网格体信息
返回PCG_FenceGen图表,创建一个Add Attribute节点,并将其放在细分样条线(Subdivide Spline)节点附近。
创建一个Get Module Info节点,将其连接到Add Attribute的In输入。
创建一个Get Mesh Info节点,将其连接到Add Attribute的Attributes输入。
将Add Attribute的Out连接到PCG_ExtractInfo子图表节点的 Mesh Info 输入。
将子图表节点的输出连接到细分样条线(Subdivide Spline)节点的Modules Info输入。
从细分样条线(Subdivide Spline)节点的输出拖出引线,创建一个Match and Set Attributes节点。 将子图表节点的输出连接到其Match Data输入。 此节点会接收来自细分样条线(Subdivide Spline)的点数据和语法,并将其与来自那些参数的模块信息(Module Info)和网格体信息(Mesh Info)进行匹配。
点击"Match and Set Attributes" 节点并对以下选项进行设置:
勾选匹配属性(Match Attributes)复选框。
将输入属性(Input Attribute)和匹配属性(Match Attribute)的值设为
Symbol。
应用枢轴偏移变换
从Match and Set Attribute的输出拖出引线创建Multiply节点。此节点会使用来自PCG_ExtractInfo子图表的数据缩放每一个网格体的枢轴。
从Match and Set Attribute节点的输出拖出引线,将其连接到Multiply节点的In B输入。
点击Multiply节点。 将Input Source 1值设为
PivotOffset,Input Source 2值设为$Scale。从Multiply节点拖出引线,创建一个Vector: Transform Direction节点。 此节点会旋转枢轴,以匹配样条线上的点。
从Multiply节点的输出拖出引线,连接到Vector: Transform Direction节点的Transform输入。
点击新节点,将操作(Operation)设为变换方向(Transform Direction)。
将Input Source 1值设为
PivotOffset,Input Source 2值设为$Transform。从Vector: Transform Direction节点拖出引线,新建一个Add节点。 此节点会将最终枢轴偏移加到网格体枢轴的位置上。
从Vector: Transform Direction的输出拖出引线,连接到Add节点的In B输入。
将Input Source 1值设为
$Position,Input Source 2值设为PivotOffset。
生成静态网格体
从Add节点的输出拖出引线,新建一个Static Mesh Spawner节点。 此节点将沿样条线生成静态网格体。
在细节面板中,将网格体选择器类型(Mesh Selector Type)设为PCGMeshSelectorByAttribute。
将属性名称(Attribute Name)值设为
Mesh。保存图表。
点击关卡中的FenceSpline Actor。 在细节面板中,选择PCG组件并使用下拉菜单将图表(Graph)选项设为PCG_FenceGen。
结果
你应该会看到一系列栅栏静态网格体按着样条线的长度方向生成出来。
你还可以为语法添加符号,在模块信息(Modules Info)中定义它们,并在网格体信息(Meshes Info)中为它们分配静态网格体,从而提升静态网格体的多样性。 这可以在图表中进行,也可以使用参数重载(Parameter Overrides)在实例上逐个进行。
在下面的示例中,栅栏行还具有以下特征:
柱子使用符号
P。门使用符号
G。大破损分段使用符号
BL。小破损分段使用符号
BS。
语法已更新为{[A,P]:2,[BL,P]:1,[BS,P]:1}*,[G,P], {[A,P]:2,[BL,P]:1,[BS,P]:1}*。