Hello everyone,
I am new to Unreal Engine, and for the past two weeks, I have been working the basics, and trying to do some cool stuff. For my first project, I am thinking of having a character that can cut everything in a level.
I have pretty much nailed cutting static meshes by transforming it into procedural meshes.
The problem arises with Skeletal Meshes. I tried to go with the same approach of converting the skeletal mesh to a procedural mesh, so that then I could go ahead and cut it.
I found some threads, such as this one: https://forums.unrealengine.com/t/create-procedural-mesh-from-animated-skeletal-mesh/429492/11 in which everyone seems to have solved what they were looking for. I tried to use the code provided, but I can’t seem to figure it out.
My code at the moment looks like this:
#include "my_class.h"
#include "Components/SkeletalMeshComponent.h"
#include "Rendering/MultiSizeIndexContainer.h"
#include "Rendering/SkeletalMeshLODRenderData.h"
#include "Rendering/SkeletalMeshRenderData.h"
void AMyClass::ConvertSkeletalMeshToProceduralMesh(USkeletalMeshComponent* InSkeletalMeshComponentnnn, int32 LODIndex, UProceduralMeshComponent* InProcMeshComponent)
{
FSkeletalMeshRenderData* SkMeshRenderData = InSkeletalMeshComponentnnn->GetSkeletalMeshRenderData();
const FSkeletalMeshLODRenderData& DataArray = SkMeshRenderData->LODRenderData[LODIndex];
FSkinWeightVertexBuffer& SkinWeights = *InSkeletalMeshComponentnnn->GetSkinWeightBuffer(LODIndex);
TArray<FVector> VerticesArray;
TArray<FVector> Normals;
TArray<FVector2D> UV;
TArray<FColor> Colors;
TArray<FProcMeshTangent> Tangents;
for (int32 j = 0; j < DataArray.RenderSections.Num(); j++)
{
//get num vertices and offset
const int32 NumSourceVertices = DataArray.RenderSections[j].NumVertices;
const int32 BaseVertexIndex = DataArray.RenderSections[j].BaseVertexIndex;
for (int32 i = 0; i < NumSourceVertices; i++)
{
const int32 VertexIndex = i + BaseVertexIndex;
//get skinned vector positions
const FVector3f SkinnedVectorPos = USkeletalMeshComponent::GetSkinnedVertexPosition(
InSkeletalMeshComponentnnn, VertexIndex, DataArray, SkinWeights);
//VerticesArray.Add(fromFVector3f(SkinnedVectorPos));
VerticesArray.Add(FVector(SkinnedVectorPos.X, SkinnedVectorPos.Y, SkinnedVectorPos.Z));
//Calc normals and tangents from the static version instead of the skeletal one
const FVector3f ZTangentStatic = DataArray.StaticVertexBuffers.StaticMeshVertexBuffer.VertexTangentZ(
VertexIndex);
const FVector3f XTangentStatic = DataArray.StaticVertexBuffers.StaticMeshVertexBuffer.VertexTangentX(
VertexIndex);
//add normals from the static mesh version instead because using the skeletal one doesnt work right.
//Normals.Add(fromFVector3f(ZTangentStatic));
Normals.Add(FVector(ZTangentStatic.X, ZTangentStatic.Y, ZTangentStatic.Z));
//add tangents
//Tangents.Add(FProcMeshTangent(fromFVector3f(XTangentStatic), false));
Tangents.Add(FProcMeshTangent(FVector(XTangentStatic.X, XTangentStatic.Y, XTangentStatic.Z), false));
//get UVs
const FVector2f SourceUVs = DataArray.StaticVertexBuffers.StaticMeshVertexBuffer.
GetVertexUV(VertexIndex, 0);
FVector2d ResUVs;
ResUVs.X = SourceUVs.X;
ResUVs.Y = SourceUVs.Y;
UV.Add(ResUVs);
//dummy vertex colors
Colors.Add(FColor(0.0, 0.0, 0.0, 255));
}
}
//get index buffer
FMultiSizeIndexContainerData IndicesData;
DataArray.MultiSizeIndexContainer.GetIndexBuffer(IndicesData.Indices);
for (int32 j = 0; j < DataArray.RenderSections.Num(); j++)
{
TArray<int32> Tris;
// get number triangles and offset
const int32 SectionNumTriangles = DataArray.RenderSections[j].NumTriangles;
const int32 SectionBaseIndex = DataArray.RenderSections[j].BaseIndex;
//iterate over num indices and add triangles
for (int32 i = 0; i < SectionNumTriangles; i++)
{
int32 TriVertexIndex = i*3 + SectionBaseIndex;
Tris.Add(IndicesData.Indices[TriVertexIndex]);
Tris.Add(IndicesData.Indices[TriVertexIndex + 1]);
Tris.Add(IndicesData.Indices[TriVertexIndex + 2]);
}
//Create the procedural mesh section
InProcMeshComponent->CreateMeshSection(j, VerticesArray, Tris, Normals, UV, Colors, Tangents, true);
}
}
In UE I instantiate a blueprint from that class (derives from AActor), and in the construction script I have this:
The static mesh is hidden in-game, so I should only see the procedural mesh.
But what happens is that the procedural mesh just falls through the bottom of the level, never to be seen again lol. Is this a problem with collisions? A problem with the code? What can I do?
I tried a lot of setting changes, but nothing seems to work my way.
Sorry for the long text