虚幻引擎程序化资源生成框架PCG 之 UPCGBlueprintElement源码笔记(一)

UPCGBlueprintElement是PCGGraph的基础,用于自定义节点。关键函数包括Execute和ExecuteWithContext,用于执行节点逻辑。LoopBody函数(如PointLoopBody,VariableLoopBody)需配合Loop函数使用,通过FPCGAsync的异步处理进行1:1或1:N的循环操作。NestedLoopBody和IterationLoopBody提供了更复杂的循环控制。这些函数提供了高度定制的图形生成能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

UPCGBlueprintElement是PCGGraph中自定义节点的基类,但官方目前还没有给出详细的文档,所以从源代码里找点答案。

在这里插入图片描述

可覆盖函数(Override Functions)

在这里插入图片描述

UPCGBlueprintElement是PCGGraph中所有自定义节点的基类,有如下几个可供蓝图覆盖的函数:

  • Excute
  • Excute with Context
  • Iteration Loop Body
  • Point Loop Body
  • Variable Loop Body
  • Nested Loop Body
  • Node Color Override
  • Node Title Override
  • Node Type Override

其中 ExcuteExcute with ContextNodeTitleOverrideNodeColorOverrideNodeTypeOverride是覆盖后被自动触发的;而剩余的几个“Loop Body函数”则需要在蓝图中显示调用对应的“Loop函数”才可以执行循环,比如:要调用PointLoop才可以执行Point Loop Body

Excute 和 Excute with Context

这两个函数可以理解为自定义节点的“主函数”,区别就是一个有PCGContext输入另一个没有,ExecuteWithContext会调用Execute

Excute

	UFUNCTION(BlueprintImplementableEvent, BlueprintCallable, Category = "PCG|Execution")
	void Execute(const FPCGDataCollection& Input, FPCGDataCollection& Output);

Excute with Context

	UFUNCTION(BlueprintNativeEvent, Category = "PCG|Execution")
	void ExecuteWithContext(UPARAM(ref)FPCGContext& InContext, const FPCGDataCollection& Input, FPCGDataCollection& Output);
void UPCGBlueprintElement::ExecuteWithContext_Implementation(FPCGContext& InContext, const FPCGDataCollection& Input, FPCGDataCollection& Output)
{
	Execute(Input, Output);
}

其实还有个C++ 函数ExecuteInternalExcute with Context是由它调用的。

virtual bool ExecuteInternal(FPCGContext* Context) const override;
	/** Finally, execute the actual blueprint */
		Context->BlueprintElementInstance->ExecuteWithContext(*Context, Context->InputData, Context->OutputData);

Loop Body函数和Loop函数

在这里插入图片描述

Loop Body函数都是在Loop函数中定义的lambda表达式调用的。

  • Point Loop BodyNested Loop BodyIteration Loop Body通过FPCGAsync::AsyncPointProcessing调用;
  • Variable Loop Body通过FPCGAsync::AsyncMultiPointProcessing调用
  • 上述节点中的各种Data参数都是PCGPointData类型,需要的话可以在调用Loop函数的时候传入,它们会直接传入Loop Body函数

Point Loop Body和PointLoop

Point Loop Body需要通过PointLoop执行循环

Point Loop Body
在这里插入图片描述

PointLoop

	FPCGAsync::AsyncPointProcessing(&InContext, InPoints.Num(), OutPoints, [this, &InContext, InData, OutData, &InPoints](int32 Index, FPCGPoint& OutPoint)
	{
		return PointLoopBody(InContext, InData, InPoints[Index], OutPoint, OutData->Metadata);
	});

Variable Loop Body和VariableLoop

Variable Loop Body需要通过VariableLoop执行循环

在这里插入图片描述

VariableLoop

	FPCGAsync::AsyncMultiPointProcessing(&InContext, InPoints.Num(), OutPoints, [this, &InContext, InData, OutData, &InPoints](int32 Index)
	{
		return VariableLoopBody(InContext, InData, InPoints[Index], OutData->Metadata);
	});
}

FPCGAsync::AsyncPointProcessingFPCGAsync::AsyncMultiPointProcessing都是异步的,它们的区别就在于处理输入:输出为1:1还是1:N的循环。Point Loop BodyVariableLoopBody,前者输入一个point返回一个point;后者输入一个point可以返回一个point的数组。比如:如果你想把一个point看作一块地基,想在它的垂直上方再生成一串点作为楼层,然后把这些点返回,那么你就需要用到VariableLoopBody

Nested Loop Body和NestedLoop

Nested Loop Body需要通过NestedLoop执行循环

在这里插入图片描述
关键代码如下,但使用情景没想明白。

NestedLoop

	const TArray<FPCGPoint>& InOuterPoints = InOuterData->GetPoints();
	const TArray<FPCGPoint>& InInnerPoints = InInnerData->GetPoints();
	TArray<FPCGPoint>& OutPoints = OutData->GetMutablePoints();

	FPCGAsync::AsyncPointProcessing(&InContext, InOuterPoints.Num() * InInnerPoints.Num(), OutPoints, [this, &InContext, InOuterData, InInnerData, OutData, &InOuterPoints, &InInnerPoints](int32 Index, FPCGPoint& OutPoint)
	{
		return NestedLoopBody(InContext, InOuterData, InInnerData, InOuterPoints[Index / InInnerPoints.Num()], InInnerPoints[Index % InInnerPoints.Num()], OutPoint, OutData->Metadata);
	});

Iteration Loop Body和IterationLoop

Iteration Loop Body需要通过IterationLoop执行循环

在这里插入图片描述

Point Loop Body一样,但它会提供一个NumIterations用于指定迭代次数

IterationLoop

	FPCGAsync::AsyncPointProcessing(&InContext, NumIterations, OutPoints, [this, &InContext, InA, InB, OutData](int32 Index, FPCGPoint& OutPoint)
	{
		return IterationLoopBody(InContext, Index, InA, InB, OutPoint, OutData->Metadata);
	});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

开发游戏的老王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值