UE5.7的Groom Dataflow的模拟,在动态创建的角色上不生效

​groom在UE5.7出了dataflow的功能,我希望用这个功能让动画驱动groom

但是我发现,只有在我做成一个蓝图预设的时候,dataflow才能生效。而动态创建component再修改Mesh deformer,模拟就失效了。

是不是动态挂载的方式还需要调用一些其他的初始化​接口?

我还遇到很迷惑的现象,在附件工程里好像出不来,但是在我自己的工程里,我只要双击打开groom asset,或者场景里摆放一个蓝图拼好的dataflow角色​,有概率突然就能成功模拟了,但是下次启动引擎就又失效了。这里是不是有cache相关的操作?

[Attachment Removed]

奇怪。附件没上传成功吗,我再传一次。

重现步骤:

打开附件工程的DataflowBug关卡

可以看到关卡里有两个蓝图,一个是内容实例里的Aera角色,他有Dataflow模拟的头发,头发能正常绕到肩膀另一头。

第二个蓝图BP_DynamicAera是我用动态创建Component的方式拼装的Aera,他的Dataflow模拟失效了。

[Attachment Removed]

您好,

我发现附件工程里两处设置有些问题:

  1. groom是绑定到在马尾辫子骨骼上的, 动画来源是Hair_Deform_AnimBP中的Rigid Body模拟, 但BP_DynamicAera中并没有把这个马尾骨骼加进来, 应该是下图的这个SetSkeletalMeshAsset节点填错了, 需改成Hair_L_DutchBraid_Tri.
  2. 动画驱动的groom目前需要设置AttachmentName, 将他attach到父级skeletal mesh的正确骨骼上.

[Image Removed]

修改过后, 我这边看辫子的动画表现是正常的. [Image Removed]

[Attachment Removed]

非常感谢,确实是这样,原来AttachmentName需要设置。顺便还有一个刚刚发现的问题,左边这个蓝图拼好的角色,如果我把他Attach到随便一个东西上,他的dataflow也不动了,这个是不是个bug。 [Image Removed]​

[Attachment Removed]

这应该是个bug. 原因是在groom的mesh deformer里, 查找骨骼动画来源的Skeletal Mesh的逻辑是GetAttachmentRootActor, 也就是从attach到的根Actor上找. 具体参考DeformerGroomInterfaceUtils.h中的GetGroupSkelMesh.

我觉得这里改成先在Owner Actor中查找, 再到Root Actor上查找更合理一些, 可以同时覆盖蓝图封装以及groom独立挂在角色Actor上的情况, 如下, 测试可以修复.

后面我再问下开发怎么修复合适, 有更新和你沟通, 感谢反馈!

FORCEINLINE USkeletalMeshComponent* GetGroupSkelMesh(const UGroomComponent* GroomComponent, const int32 GroupIndex, int32& MeshLOD)
{
	if (GroomComponent)
	{
		auto FindInActor = [&](AActor* Actor) -> USkeletalMeshComponent*
		{
			if (!Actor) { return nullptr; }
			TArray<UActorComponent*> ActorComponents;
			Actor->GetComponents(USkeletalMeshComponent::StaticClass(), ActorComponents);
			for (UActorComponent* ActorComponent : ActorComponents)
			{
				if (USkeletalMeshComponent* SkeletalMeshComponent = Cast<USkeletalMeshComponent>(ActorComponent))
				{
					if (GroomComponent->GroomAsset && (SkeletalMeshComponent->GetSkeletalMeshAsset() ==
						GroomComponent->GroomAsset->GetDataflowSettings().GetSkeletalMesh(GroupIndex)))
					{
						MeshLOD = GroomComponent->GroomAsset->GetDataflowSettings().GetMeshLOD(GroupIndex);
						return SkeletalMeshComponent;
					}
				}
			}
			return nullptr;
		};
 
		AActor* OwnerActor = GroomComponent->GetOwner();
		if (USkeletalMeshComponent* Found = FindInActor(OwnerActor))
		{
			return Found;
		}
		AActor* RootActor = GroomComponent->GetAttachmentRootActor();
		if (RootActor != OwnerActor)
		{
			if (USkeletalMeshComponent* Found = FindInActor(RootActor))
			{
				return Found;
			}
		}
	}
	MeshLOD = INDEX_NONE;
	return nullptr;
}

[Attachment Removed]