UE-通过模型的某一点坐标获取此处三角面的UV坐标

内容目录

介绍

在开发的过程中遇到了一个问题,如何快速且方便的通过点击模型的某一个位置,获得这个位置的 UV
一开始翻源码没看到,所以我本想自己造一个轮子的,大概想法就是,我点击的时候获取当前三角面索引。
此时可以获得三角面的三个顶点,那么我根据这三个顶点的位置与他们的 UV ,和我自己点击的位置进行重心坐标差值求出我点击位置的 UV 坐标。
由于我知道三角形索引,所以完全可以认为我点击的位置在三角形里面,既然每个顶点有UV坐标与其真正的坐标,那么就可以方便的计算出我点的点的 UV 坐标。


不过等我准备开始造轮子的时候,还是发现了原来 UE 有这玩意儿。

UFUNCTION(BlueprintPure, Category = "Collision")
static ENGINE_API bool FindCollisionUV(const struct FHitResult& Hit, int32 UVChannel, FVector2D& UV);

也就是你这位,他通过 FHitResult 返回的 FaceIndex ,也就是说 TriIndex ,来计算一个 UV 位置。
而且我发现我的想法和他几乎一致,那就可以直接复用了。

本来我很惊喜,结果发现 FHitResultFaceIndex 返回的结果是 -1,这肯定是不对的,如果点击空气的话是 0(在复杂检测开启的情况下)。
所以我又去看源码了,首先我去项目设置面板中勾选了
file
这个东西,让 FindCollisionUV 函数可以正常的工作。
接下来我发现,FaceIndex-1 的原因是,UE帮你封装的时候默认的 FCollisionQueryParams 对象中的 bool bReturnFaceIndex; 是关闭的!

/** Whether we want to return the triangle face index for complex static mesh traces */
bool bReturnFaceIndex;

这不对吧,你把这个封死了我怎么用啊,所以我找到了支持 FCollisionQueryParams 传入的最后一层函数,手动将 bReturnFaceIndex 勾选了。

bool TemplateClass::TemplateFunction(const UObject* WorldContextObject, const ECollisionChannel TraceChannel, FHitResult& OutResult)
{
    // Get your controller and Mouse Pos.
    // ...

    FCollisionQueryParams CollisionQueryParams(SCENE_QUERY_STAT(ClickableTrace), true);
    CollisionQueryParams.bReturnFaceIndex = true;
    const bool Result = Controller->GetHitResultAtScreenPosition(FVector2d(MouseX, MouseY), TraceChannel, CollisionQueryParams, OutResult);
    return Result;
}

如此一来,就可以非常合理的得到位置的 UV 坐标了,就和 SP 直接绘制一样。

接下来就是喜闻乐见的调库环节,你只需要用你自己修改过射线检测函数,就能正确的返回 FaceIndex ,并把 HitResult 交给 FindCollisionUV,你就能获得正确的 UV 坐标了。

滚动至顶部