yanwen 发表于 2024-1-19 13:50

UE5 PuerTS学习与实践(二)运行时更新PCGVolume

法式化内容生成(Procedural Content Generation,简称 PCG)是一个在游戏设计和开发中常用的概念。它指的是使用算法和数据驱动的方式来自动或半自动地创建游戏内容,如关卡设计、环境、角色、物品、故事线等。PCG 可以辅佐开发者以更小的工作量创建更大量和更丰硕的游戏内容。
PCG 的使用方式有很多种,可以按照需要生成确定的内容,也可以生成随机或伪随机的内容。
虚幻引擎在5.2版本更新了法式化内容生成框架,用户可以编纂器中创建本身的法式化生成图表,为场景中生成所需的内容。
虚幻引擎官方比来放出了《Electric Dreams》环境示例项目,本文为学习 PCG 常识和 Puerts 脚本编程时,做一点简单的学习笔记。
1、创建PCG所需内容

创建 PCGVolume & PCGGraph

首先创建一个 5.2 版本的工程。按照官方文档,向场景中放置一个 PCGVolume,设置合适的大小(例如 Scale(200,200,200)),将其放置在地面(Landscape)上。通过为该 PCGVolume 指定一个 PCGGraph, 即可依据 PCGGraph 中的生成法则在场景中法式化生成内容。



场景中放置PCGVolume

然后再创建两个 PCGGraph 资产,用于在运行时切换 PCGVolume 所使用的 PCGGraph, 来实现改换地表生成物的效果。



创建两个PCGGraph

两个 PCGGraph 中的法则都按照官方文档中的示例来,斗劲简单:对地形概况进行点采样,然后施加一些随机的缩放和旋转值,基于措置后的点生成静态网格体。



PCGGraph中的内容

第二个PCGGraph中的节点连线逻辑一样,只是对 Static Mesh Spawner 节点的细节面板上 Mesh Entries-Descriptor-Static Mesh 改换了一种树木。



为Static Mesh Spawner指定生成的网格体

2、运行时更新 PCGVolume 内容

颠末学习发现,可以在法式运行时,更改 PCGVolume 体积的大小,影响法式化生成内容的范围;或是更新 PCGVolume 所使用的 PCGGraph,更新场景中生成的内容。
通过查看 APCGVolume 的担任关系发现,它也是一种类型的 Actor, 它持有的 UBrushComponet 和 UPCGComponet 组件, 而 UBrushComponent 向上查几层是担任自 USceneComponent, 因此 APCGVolume 的这两个组件分袂用于控制 PCGVolume 体积的大小和法式化生成的内容。



APCGVolume的担任关系

2.1、更新 PCGVolume 影响的范围

非论是通过向 JsEnv 传递 PCGVolume 对象,还是通过 APCGVolume 的类型、或是其上打的 Tag 获取到相应的 PCGVolume 后,将其内部持有的 BrushComponent 的移动性更改为 Moveable, 然后再设置 PCGVolume 的缩放值,便可更改该 PCGVolume 影响的范围。
let PCGVolume = this.PCGVolume;
if(PCGVolume)
{
    let BrushComponent = PCGVolume.BrushComponent;
    BrushComponent.SetMobility(UE.EComponentMobility.Movable);
    PCGVolume.SetActorScale3D(new UE.Vector(500,500,500));
}
2.2、更新 PCGVolume 所用的PCGGraph

与更新 PCGVolume 的缩放大小类似,要更新 PCGVolume 所用的 PCGGraph, 仅需要多做一步操作,那就是获取到所需的 PCGGraph, 设置给 PCGVolume。
在 Puerts 中,加载资源的方式为:UE.资源类型.Load(”资源路径”),这里资源类型为 PCGGraph。获取到相应的 PCGGraph 后,使用 PCGVolume 的 PCGComponent 组件的 SetGraph() 函数,即可完成改换。
let PCGVolume = this.PCGVolume;
if(PCGVolume)
{
    let BrushComponent = PCGVolume.BrushComponent;
    BrushComponent.SetMobility(UE.EComponentMobility.Movable);
    PCGVolume.SetActorScale3D(new UE.Vector(500,500,500));
    let PCGComponent = PCGVolume.PCGComponent as UE.PCGComponent;
    if(PCGComponent)
    {
      //let GraphInstance = PCGComponent.GraphInstance as UE.PCGGraphInstance;
      {
            let NewPCGGraph = UE.PCGGraph.Load(”/Script/PCG.PCGGraph'/Game/LeranPCG/PCG_First_ForestGen_2.PCG_First_ForestGen_2'”);
            if(NewPCGGraph)
            {
                PCGComponent.SetGraph(NewPCGGraph);
            }
      }
    }
}
2.3、示例


运行时更新PCG内容
https://www.zhihu.com/video/1655718738874871808
3、更多

PCGComponent 中存储了 PCGGraph、PCGGraphInstance、PCGData、GeneratedActors、GeneratedResources 等数据,理论上可以对生成的内容做到更深层次、更细粒度的控制,后面继续研究一下这些东西。
需要注意的是,虽然 PCG 可以节省开发者的工作量并提供多样化的游戏体验,但如果使用不妥,也可能导致游戏内容的质量纷歧,或者发生玩家难以理解或者难以玩的游戏内容。因此,如何合理操作 PCG 以达到良好的游戏设计效果是一个需要深思熟虑的问题。
参考


[*]^法式化内容生成框架 https://docs.unrealengine.com/5.2/zh-CN/procedural-content-generation--framework-in-unreal-engine/
[*]^《Electric Dreams》环境 示例项目 https://www.unrealengine.com/zh-CN/electric-dreams-environment
[*]^法式化内容生成概述 | 虚幻引擎5.2文档 (unrealengine.com) https://docs.unrealengine.com/5.2/zh-CN/procedural-content-generation-overview/
页: [1]
查看完整版本: UE5 PuerTS学习与实践(二)运行时更新PCGVolume