作者yekdniw (yekdniw)
看板GameDesign
标题[程式] UE4 揭密SpawnActor的BP节点
时间Sat Jan 12 13:52:10 2019
网页版
https://yekdniwue.blogspot.com/2019/01/spawnactorbp.html
在BP的SpawnActor节点有个厉害的功能
就是你给不同的class type的话,这个节点会根据class type产生不同的样貌,
主要有两个:
1. return的actor type会是你传入的class type,而不是基础type actor,
还要自己cast
2. 如果传入的class有expose on spawn的变数,也会再这里列举出来让你可以传入
在说明细节之前,我们先看一下C++处理 expose on spawn的变数值是如何设定的。
AMyActor* pActor = SpawnActorDeferred;
// Fill your variable here...
FinishSpawningActor(pActor);
所以可以知道其实spawn一个拥有expose on spawn的actor是要作上述三个步骤的。
Spawn -> SetProperties -> FinishSpawn
如果因为某些因素没呼叫到最後的FinishSpawn,程式的运作就会有问题。
而BP的SpawnActorFromClass只用了一个节点就作到上述三件事情,
为了理解其中的奥妙,我花了一些时间追查,在这边分享一下。
程式码在
Engine\Source\Editor\BlueprintGraph\Classes\K2Node_SpawnActorFromClass.h
在function ExpandNode里面,就是处理一个节点其实会分成三大节点的主函式。
static const FName BeginSpawningBlueprintFuncName =
GET_FUNCTION_NAME_CHECKED(
UGameplayStatics,
BeginDeferredActorSpawnFromClass);
static const FName FinishSpawningFuncName =
GET_FUNCTION_NAME_CHECKED(
UGameplayStatics,
FinishSpawningActor);
上面两行可以看到会从UGameplayStatics之中
取出BeginDeferredActorSpawnFromClass以及FinishSpawningActor
的两个函式名称出来。
代表SpawnActor的节点实际上在Spawn跟FinishSpawn阶段就是对应到呼叫
BeginDeferredActorSpawnFromClass以及FinishSpawningActor
[图1.]
上面这段定义SpawnActor这个BP节点会有的各个连接点
[图2.]
上面这段定义呼叫
UGameplayStatics::BeginDeferredActorSpawnFromClass的各个连接点
接下来的程式码就是把SpawnActor的各个连接点,
一个个导向CallBeginSpawnNode的各个连接点。
使用的主要函式是CompilerContext.MovePinLinksToIntermediate
[图3.]
上面这段定义呼叫UGameplayStatics::FinishSpawningActor的各个连接点
图中如果有需要最外层的连接点连向CallFinishSpawnNode,可以使用
CompilerContext.CopyPinLinksToIntermediate
例如
CompilerContext.CopyPinLinksToIntermediate(
*CallBeginTransform,
*CallFinishTransform);
就是把外部传入的Transform座标一路往後带到FinishSpawningActor函式内
最後,处理expose on spawn的部分在这一行
UEdGraphPin* LastThen =
FKismetCompilerUtilities::GenerateAssignmentNodes(
CompilerContext,
SourceGraph,
CallBeginSpawnNode,
SpawnNode,
CallBeginResult,
ClassToSpawn );
里面会根据传入的class,找到class内有expose on spawn的properties,
然後根据这些properties建立set variable节点
函式最後一行SpawnNode->BreakAllNodeLinks();
把原来的结点所有的连结断掉,因为我们已经把使用者看到的节点
SpawnNode替换成三大节点:
CallBeginSpawnNode -> AssignmentNodes -> CallFinishSpawnNode
从这次的经验可以学习到,BP节点拥有节点替换的功能,
也就是说有的时候你看到一个节点,其实背後是有可能多作你不知道的事情。
这点可以多多拿来利用。
实际上程式码很多看起来很恐怖,不过慢慢看的话其实不算是太难懂的东西。
这边作个纪录也顺便分享一下学到的东西。
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 36.230.64.44
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/GameDesign/M.1547272333.A.DCD.html
1F:推 InvincibleK: 感谢分享 01/12 18:48
2F:推 coolrobin: 推推 01/12 23:52
3F:推 nickchu35: 推,UE source code 有时间钻真的会学到很多 01/13 14:30
※ 编辑: yekdniw (59.120.146.90 台湾), 07/15/2020 11:07:05