欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

UE4开启SkeletalMesh三角面碰撞失败(EnableperpolyCollision无效)

程序员文章站 2024-03-16 20:37:34
...

解决方案:不要在角色蓝图里的SkeletalMeshComponent里面勾选EnableperpolyCollision,要找到SkeletalMesh资源蓝图,在资源蓝图里面勾选EnableperpolyCollision。(在UE4官方论坛也有人问过)

分析:这可能是UE引擎里面的一个Bug。为了完全弄清这个Bug,我特意跟踪了一下代码,想深入了解原因的可以继续往下看。
首先要知道,开启一个三角面的复杂碰撞需要经过一个物理Cook过程,这个过程就是将SkeletalMesh的渲染数据(三角面顶点信息)保存,然后Physics引擎根据这些顶点来计算出一个复杂的物理碰撞体。
这个Cook后的信息同时与他的对应平台会作为一个结构体保存在BodySetup的CookedFormatData数组里面,但是这个数组里面指向Cook的指针可能为空(如果对物理BodySetup等信息不了解,建议先看看这篇文档 UE4物理模块分析)。

CookedFormatData
FormatName:
CookedDataPointer:

那问题就出在这个BodySetUp上面,SkeletalMeshComponent与SkeletalMesh都有一个BodySetup成员,当我们在角色蓝图里面勾选SkeletalMeshComponent的EnableperpolyCollision时。他会获取SkeletalMesh的BodySetup的CookedFormatData来判断当前是否有Cook数据,如果有的话就会跳过Cook过程。

void USkeletalMeshComponent::OnCreatePhysicsState()
{
 // UE_LOG(LogSkeletalMesh, Warning, TEXT("Creating Physics State (%s : %s)"), *GetNameSafe(GetOuter()),  *GetName());
 // Init physics
 if (bEnablePerPolyCollision == false)
 {
  InitArticulated(GetWorld()->GetPhysicsScene());
  USceneComponent::OnCreatePhysicsState(); // Need to route CreatePhysicsState, skip PrimitiveComponent
 }
 else
 {
  CreateBodySetup();
  BodySetup->CreatePhysicsMeshes();
  Super::OnCreatePhysicsState(); //If we're doing per poly we'll use the body instance of the primitive component
 }

 // Notify physics created
 OnSkelMeshPhysicsCreated.Broadcast();
}

而当我们勾选SkeletalMesh资源文件里面的EnableperpolyCollision时,他会先把之前Cook的数据清空,然后再去判断是否需要Cook,这时候没有Cook数据肯定是需要Cook的。

#if WITH_EDITOR
void USkeletalMesh::BuildPhysicsData()
{
 CreateBodySetup();
 BodySetup->CookedFormatData.FlushData(); //we need to force a re-cook because we're essentially re-creating the bodysetup so that it swaps whether or not it has a trimesh
 BodySetup->InvalidatePhysicsData();
 BodySetup->CreatePhysicsMeshes();
}
#endif

进一步再深入一点就是既然SkeletalMesh里面有Cook过的数据,直接用他Cook数据不就可以了?因为编辑器加载SkeletalMeshComponent的时候就会尝试去获取Cook后的信息,如果没有Cook后的信息就会尝试去进行Cook。不过这时候需要执行ContainsPhysicsTriMeshData判断当前对象是否有三角面信息。如果有的话才会进一步的进行Cook。如果没有的话,那就是空的Cook后的信息。所以无论是不是空的,这个数据都会返回给SkeletalMesh的BodySetup的CookedFormatData。这样,CookedFormatData虽然有这样一个平台以及对应的Cooked数据成员,但是里面的Cooked数据可能是空的。

原文链接(转载请标明):http://blog.csdn.net/u012999985/article/details/78698971