Procedural Mesh isn't visible

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)

I really dont want to have to build this out in blueprints. I’d imagine it will be really slow.

bump

Your code works just a matter if you are calling it from c++ or bp?

obraz

Just that it’s generating the polygons in the wrong order (flipped normals)

Also are you calling the code directly from bp? Is it triggering?

If I wanted to run a test call of the code I implemented it as a blueprintNativeEvent

UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
void GenerateGround(AGrid* Grid);
virtual void GenerateGround_Implementation(AGrid* Grid);

Where the c++ version is GenerateGround_Implementation

If at 0,0,0 the builder overlaps the debug

If you want to reverse the polygon try


        // Create triangles for this quad
        Triangles.Add(VertexIndex + 2);
        Triangles.Add(VertexIndex + 1);
        Triangles.Add(VertexIndex + 0);

        Triangles.Add(VertexIndex + 0);
        Triangles.Add(VertexIndex + 3);
        Triangles.Add(VertexIndex + 2);

You’re always swooping in to help me! You’re the best. Thanks

This worked. Weird. I am calling it from blueprints. I had previous tried flipping the normals to -1 to see if that was the issue and it didn’t do anything. Wouldnt that have that the same effect as adding the triangles in a different order?

Perhaps but flipping normals is a rather unnatural way to get around it. If you know the natural way a truangle is suposed to face then why add extra steps?

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.