UE | Slice Procedural Mesh 實現動態切割模型
Procedural Mesh 程式化網格體
Create Mesh Section 生成模型網格體
SectionIndex
:建立或者替換的面的id,預設為0Vertices
: 三角形的頂點,排列順序會影響Triangles
陣列中的索引Triangles
:組成三角形的頂點索引,一般情況下為順時針Normals
: 頂點的法線資訊,與第二個引數順序一致,陣列大小一致(可不填)UV0 UV1 UV2
:頂點的UV資訊,與第二個引數順序一致,陣列大小一致(可不填)VertexColors
:頂點的顏色資訊(可不填)Tangents
:頂點的切線資訊(可不填)bCreateCollision
:是否建立碰撞資訊(注意:此處的碰撞是複雜碰撞資訊)
Copy ProceduralMesh From StaticMeshComponent 複製模型資料
SliceProceduralMesh 切割程式化模型
Plane Position
:世界座標系下該平面的中心位置Plane Normal
:世界座標系下該平面的發現Create Other Half
: 是否將切下來的那一塊模型獨立出來Cap Option
: 切面狀態No Cap
: 切面不縫合,模型中空Create New Section for Cap
: 切面縫合,使用自定義的材質Use Last Section for Cap
: 切面縫合,使用與模型一樣的材質
Cap Material
: 如果Cap Option是Create New Section for Cap時自定義的材質
程式碼實現
b Allow CPU Access
開啟bAllowCPUAccess
,才能動態切割模型
AActor* actor = SpawnSkirtingLine->Create();
if (actor == nullptr) {
return;
}
UStaticMeshComponent* component = Cast<UStaticMeshComponent>(actor->GetRootComponent());
if (!component->GetStaticMesh()->bAllowCPUAccess) {
PrintStr("SkirtingLine not bAllowCPUAccess");
return;
}
Procedural Mesh Component
新建程式化模型元件copyComponent
,透過Copy ProceduralMesh From StaticMeshComponent
函式複製Actor
中StaticMesh
資料到程式化模型ProceduralMesh
中
UProceduralMeshComponent* copyComponent = NewObject<UProceduralMeshComponent>(actor, *("copy" + FString::FromInt(index++)));
copyComponent->SetupAttachment(component);
copyComponent->RegisterComponent();
copyComponent->SetCollisionEnabled(ECollisionEnabled::NoCollision);
UKismetProceduralMeshLibrary::CopyProceduralMeshFromStaticMeshComponent(component, 0, copyComponent, true);
copyComponent->SetWorldLocation((x + z) / 2);
copyComponent->SetWorldRotation(normal.Rotation() + FRotator(0, -90, 0));
Slice Procedural Mesh
切割模型
FVector sliceStart = y; //裁剪開始點
UProceduralMeshComponent* cutComponent = nullptr;
EProcMeshSliceCapOption capOption = EProcMeshSliceCapOption::UseLastSectionForCap; //Cap Option
FVector sliceNormal = y - z; //裁剪平面的法向量
UKismetProceduralMeshLibrary::SliceProceduralMesh(copyComponent, sliceStart, sliceNormal, false, cutComponent, capOption, nullptr);