Context: I have a class that randomly generates an irregular (non-rectangular winding path) grid with some guidelines. I now want to use those grid points (int points) to generate a procedural mesh as the ground. Using these blueprint nodes:
I can get a basic 10x10 procedural mesh to show up in game, but my c++ class for the greater grid isn’t working. I’ve tried everything: Changing materials, trying default materials, using color enum for vertex colors, simplifying the grid to test for performance issues, setting visibility, registering component, disabling collision, checking to see if all input tables into the create mesh function have same length, etc etc)
The inputted dataset’s list of int points is correct. I’ve exhausted all suggestions online and I’ve asked ChatGPT (of course not helpful). Any suggestions?
#include "GroundBuilder.h"
AGroundBuilder::AGroundBuilder()
{
PrimaryActorTick.bCanEverTick = true;
MeshComponent = CreateDefaultSubobject<UProceduralMeshComponent>(TEXT("GeneratedMesh"));
RootComponent = MeshComponent;
}
void AGroundBuilder::BeginPlay()
{
Super::BeginPlay();
}
void AGroundBuilder::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void AGroundBuilder::GenerateGround(AGrid* Grid)
{
if (!Grid) return;
// Get the GridData from the Grid class
const TMap<FIntPoint, FGridTile>& GridData = Grid->GridData; // Replace FYourStruct with your actual value type
// Clear any existing mesh data
MeshComponent->ClearAllMeshSections();
// Create the new mesh from the grid data
CreateMeshSectionFromGridData(GridData);
}
void AGroundBuilder::CreateMeshSectionFromGridData(const TMap<FIntPoint, FGridTile>& GridData)
{
TArray<FVector> Vertices;
TArray<int32> Triangles;
TArray<FVector> Normals;
TArray<FVector2D> UVs;
TArray<FLinearColor> VertexColors;
TArray<FProcMeshTangent> Tangents;
int32 VertexIndex = 0;
for (const TPair<FIntPoint, FGridTile>& Entry : GridData)
{
FIntPoint GridPoint = Entry.Key;
// Create four vertices for each grid point (assuming square tiles)
Vertices.Add(FVector(GridPoint.X * 100.0f, GridPoint.Y * 100.0f, 400.0f));
Vertices.Add(FVector((GridPoint.X + 1) * 100.0f, GridPoint.Y * 100.0f, 400.0f));
Vertices.Add(FVector((GridPoint.X + 1) * 100.0f, (GridPoint.Y + 1) * 100.0f, 400.0f));
Vertices.Add(FVector(GridPoint.X * 100.0f, (GridPoint.Y + 1) * 100.0f, 400.0f));
// Create triangles for this quad
Triangles.Add(VertexIndex + 0);
Triangles.Add(VertexIndex + 1);
Triangles.Add(VertexIndex + 2);
Triangles.Add(VertexIndex + 2);
Triangles.Add(VertexIndex + 3);
Triangles.Add(VertexIndex + 0);
// Increment the vertex index for the next quad
VertexIndex += 4;
// Add placeholder data for normals, UVs, vertex colors, and tangents
Normals.Add(FVector(0.0f, 0.0f, 1.0f)); // Up direction
Normals.Add(FVector(0.0f, 0.0f, 1.0f));
Normals.Add(FVector(0.0f, 0.0f, 1.0f));
Normals.Add(FVector(0.0f, 0.0f, 1.0f));
UVs.Add(FVector2D(0.0f, 0.0f));
UVs.Add(FVector2D(1.0f, 0.0f));
UVs.Add(FVector2D(1.0f, 1.0f));
UVs.Add(FVector2D(0.0f, 1.0f));
VertexColors.Add(FLinearColor(1.f, 0.f, 0.f));
VertexColors.Add(FLinearColor(1.f, 0.f, 0.f));
VertexColors.Add(FLinearColor(1.f, 0.f, 0.f));
VertexColors.Add(FLinearColor(1.f, 0.f, 0.f));
Tangents.Add(FProcMeshTangent(1.0f, 0.0f, 0.0f));
Tangents.Add(FProcMeshTangent(1.0f, 0.0f, 0.0f));
Tangents.Add(FProcMeshTangent(1.0f, 0.0f, 0.0f));
Tangents.Add(FProcMeshTangent(1.0f, 0.0f, 0.0f));
}
for (int32 i = 0; i < Triangles.Num(); i += 3)
{
FVector V0 = Vertices[Triangles[i]];
FVector V1 = Vertices[Triangles[i + 1]];
FVector V2 = Vertices[Triangles[i + 2]];
DrawDebugLine(GetWorld(), V0, V1, FColor::Green, true, -1.0f, 0, 2.0f);
DrawDebugLine(GetWorld(), V1, V2, FColor::Green, true, -1.0f, 0, 2.0f);
DrawDebugLine(GetWorld(), V2, V0, FColor::Green, true, -1.0f, 0, 2.0f);
}
UE_LOG(LogTemp, Warning, TEXT("Vertices Count: %d"), Vertices.Num());
UE_LOG(LogTemp, Warning, TEXT("Triangles Count: %d"), Triangles.Num());
UE_LOG(LogTemp, Warning, TEXT("UVs Count: %d"), UVs.Num());
UE_LOG(LogTemp, Warning, TEXT("VertexColors Count: %d"), VertexColors.Num());
UE_LOG(LogTemp, Warning, TEXT("Tangents Count: %d"), Tangents.Num());
UE_LOG(LogTemp, Warning, TEXT("Normals Count: %d"), Normals.Num());
if (!MeshComponent || !MeshComponent->IsRegistered())
{
UE_LOG(LogTemp, Warning, TEXT("MeshComponent is not properly initialized or registered."));
return;
}
// Create the mesh section
MeshComponent->CreateMeshSection_LinearColor(0, Vertices, Triangles, Normals, UVs, VertexColors, Tangents, false);
UMaterial* Material = LoadObject<UMaterial>(nullptr, TEXT("Material'/Game/Art/Materials/M_testtexture1.M_testtexture1'"));
MeshComponent->SetMaterial(0, Material);
//UMaterial* DefaultMaterial = UMaterial::GetDefaultMaterial(MD_Surface);
//MeshComponent->SetMaterial(0, DefaultMaterial);
MeshComponent->SetVisibility(true);
MeshComponent->SetHiddenInGame(false);
MeshComponent->MarkRenderStateDirty();
}
Here’s the results: You can see the blueprint proc mesh in the top left, but for the actual grid the only thing im getting is my debug lines (far right overlapping actual grid)