UE4开启SkeletalMesh三角面碰撞失败(EnableperpolyCollision无效)
解决方案:不要在角色蓝图里的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
上一篇: unity 简单手势判断(一)
下一篇: #对称加密和非对称加密