Hi, I’m trying to render a generated mesh, and I don’t understand how to create a material and assign it to my mesh component, using C++.
Here’s my header:
#include "GameFramework/Actor.h"
#include "ProceduralMeshComponent.h"
#include "MyActor.generated.h"
UCLASS()
class PROCEDURALMESH_API AMyActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AMyActor();
// Called when the game starts or when spawned
virtual void BeginPlay() override;
// Called every frame
virtual void Tick( float DeltaSeconds ) override;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = General) UProceduralMeshComponent* mesh;
USphereComponent* SphereComponent;
TArray<FVector> vertices;
TArray<int32> triangles;
TArray<FVector> normals;
TArray<FVector2D> UV0;
TArray<FColor> vertexColors;
TArray<FProcMeshTangent> tangents;
const int segs = 10;
const int divs = 24;
const float segHeight = 250;
const float baseRadius = 500;
};
Here’s my class:
#include "ProceduralMesh.h"
#include "MyActor.h"
// Sets default values
AMyActor::AMyActor()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
//UPROPERTY(EditAnywhere);
SphereComponent = CreateDefaultSubobject<USphereComponent>(TEXT("RootComponent"));
RootComponent = SphereComponent;
mesh = CreateDefaultSubobject<UProceduralMeshComponent>(TEXT("GeneratedMesh"));
}
// Called when the game starts or when spawned
void AMyActor::BeginPlay()
{
int a = 0;
int d = 0;
float radius = baseRadius;
//generate cylinder vertices
for (int i = 0; i <= divs*segs; i++)
{
//random chance to alter the radius
int chance = FMath::FRandRange(0, 3);
if (chance == 1)
{
radius += baseRadius / 100;
}
else if (chance == 2)
{
radius -= baseRadius / 100;
}
else if (chance == 3)
{
//increment back to baseRadius
radius += (baseRadius - radius) / 3;
}
//generate points in a circle
float angle = (2 * PI) / divs * a;
float z = (radius*sin(angle));
float y = (radius*cos(angle));
float x = d;
vertices.Add(FVector(x, y, z));
a += 1;
if (a == divs)
{
a = 0;
d += segHeight;
}
}
//create triangles from vertices
for (int i = 0; i < vertices.Num(); i++)
{
if (i > divs && i%divs == 0)
{
triangles.Add(i - divs);
triangles.Add(i - 1);
triangles.Add(i - (divs + 1));
triangles.Add(i - divs * 2);
triangles.Add(i - divs);
triangles.Add(i - (divs + 1));
}
else if (i > divs)
{
triangles.Add(i);
triangles.Add(i - 1);
triangles.Add(i - (divs + 1));
triangles.Add(i);
triangles.Add(i - (divs + 1));
triangles.Add(i - divs);
}
}
//displace verts to resemble cave
for (int i = 0; i < vertices.Num(); i++)
{
if (vertices[i].Z < 0 - baseRadius / 2)
{
vertices[i].Z = FMath::FRandRange(0 - (baseRadius + baseRadius / 4), 0 - baseRadius / 3);
}
vertices[i].Y += FMath::FRandRange(0 - baseRadius / 20, baseRadius / 20);
}
mesh->CreateMeshSection(1, vertices, triangles, TArray<FVector>(), TArray<FVector2D>(), TArray<FColor>(), TArray<FProcMeshTangent>(), true);
mesh->AttachTo(RootComponent);
Super::BeginPlay();
}
The mesh generates and renders in-game, but it’s just this default gray, and I was hoping to use a custom material for it. If someone could teach me how to add a custom material into this code, it’d be much appreciated!
Thanks!