Hi to all my fellow Unreal friends.
Just a little back ground first to give some context. I am attempting to build my own Voxel system for controlling my games terrain. To that end I have used the example of procedural generated mesh’s from GitHub - SRombauts/UE4ProceduralMesh: UE4.7 Procedural Mesh Generation plugin. To allow me to do what I want to do I have built a set of my own c++ class’s that don’t inherit from any of the unreal classes. These helper classes allow me to build and track all of the procedural geometry to form a chuck. The Chuck is what I hope will keep the mesh count down.
But I am having trouble with my none unreal classes not remembering the correct values that they are working with. So when I step through the code I litteraly cannot use my Visual studio to inspect my varibles as the IDE is informing me that the variable don’t exist… Here is the the function in my none unreal class that’s exhibiting this behaviour.
void Block::Blockdata(AChunk* chunk, INT32 X, INT32 Y, INT32 Z, TArray<FMeshDataTriangle>& Triangles)
{
FVector BlockCenter((float)((float)X*chunk->BlockSize) + chunk->BlockSizeHalf,
(float)((float)Y*chunk->BlockSize) + chunk->BlockSizeHalf,
(float)((float)Z*chunk->BlockSize) + chunk->BlockSizeHalf);
float ix = (float)((float)X*chunk->BlockSize) + chunk->BlockSizeHalf;
float iy = (float)((float)Y*chunk->BlockSize) + chunk->BlockSizeHalf;
float iz = (float)((float)Z*chunk->BlockSize) + chunk->BlockSizeHalf;
MeshParts meshparts;
this->CalculateVertices(chunk, BlockCenter, meshparts);
if (!chunk->GetBlock(X, Y, Z)->IsFaceSolid(Direction::down))
{
this->FaceDataUp(chunk, meshparts, Triangles);
}
if (!chunk->GetBlock(X, Y, Z)->IsFaceSolid(Direction::up))
{
this->FaceDataDown(chunk, meshparts, Triangles);
}
if (!chunk->GetBlock(X, Y, Z)->IsFaceSolid(Direction::north))
{
this->FaceDataSouth(chunk, meshparts, Triangles);
}
if (!chunk->GetBlock(X, Y, Z)->IsFaceSolid(Direction::east))
{
this->FaceDataWest(chunk, meshparts, Triangles);
}
if (!chunk->GetBlock(X, Y, Z)->IsFaceSolid(Direction::south))
{
this->FaceDataNorth(chunk, meshparts, Triangles);
}
if (!chunk->GetBlock(X, Y, Z)->IsFaceSolid(Direction::west))
{
this->FaceDataEast(chunk, meshparts, Triangles);
}
}
This code is used in this method:-
void AChunk::UpdateChunk()
{
for (int x = 0; x < CHUNKSIZE; x++)
{
for (int y = 0; y < CHUNKSIZE; y++)
{
for (int z = 0; z < CHUNKSIZE; z++)
{
blocks[x][y][z]->Blockdata(this, x, y, z, this->triangles);
}
}
}
}
Which is part of my chuck class which inhertis AActor. Which can be seen in from it’s header file.
Chunk.h
#pragma once
#include "GameFramework/Actor.h"
#include "MeshData.h"
#include "Chunk.generated.h"
class Block;
class BlockAir;
#define CHUNKSIZE 16
UCLASS()
class RTS_API AChunk : public AActor
{
GENERATED_BODY()
public:
float BlockSize;
float BlockSizeHalf;
UMeshData* mesh;
Block *blocks[CHUNKSIZE][CHUNKSIZE][CHUNKSIZE];
// Sets default values for this actor's properties
AChunk();
// Called when the game starts or when spawned
virtual void BeginPlay() override;
// Called every frame
virtual void Tick( float DeltaSeconds ) override;
Block* GetBlock(INT32 X, INT32 Y, INT32 Z);
void UpdateChunk();
private:
TArray<FMeshDataTriangle> triangles;
};
Chunk.cpp
#include “RTS.h”
#include “Chunk.h”
#include “Block.h”
#include “BlockAir.h”
// Sets default values
AChunk::AChunk()
{
static ConstructorHelpers::FObjectFinder<UMaterialInterface> Material(TEXT("Material'/Game/Materials/BaseColor.BaseColor'"));
//Set Cube Size
this->BlockSize = 100.0f;
this->BlockSizeHalf = this->BlockSize / 2;
// 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;
this->mesh = CreateDefaultSubobject<UMeshData>(TEXT("VoxelChunk"));
this->mesh->SetMaterial(0, Material.Object);
//Test Data.
for (int x = 0; x < CHUNKSIZE; x++)
{
for (int y = 0; y < CHUNKSIZE; y++)
{
for (int z = 0; z < CHUNKSIZE; z++)
{
this->blocks[x][y][z] = new BlockAir();
}
}
}
Block *test = this->blocks[3][5][2];
delete test;
this->blocks[3][5][2] = new Block();
this->UpdateChunk();
mesh->SetProceduralMeshTriangles(this->triangles);
RootComponent = mesh;
}
// Called when the game starts or when spawned
void AChunk::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AChunk::Tick( float DeltaTime )
{
Super::Tick( DeltaTime );
}
Block* AChunk::GetBlock(INT32 X, INT32 Y, INT32 Z)
{
return this->blocks[X][Y][Z];
}
void AChunk::UpdateChunk()
{
for (int x = 0; x < CHUNKSIZE; x++)
{
for (int y = 0; y < CHUNKSIZE; y++)
{
for (int z = 0; z < CHUNKSIZE; z++)
{
blocks[x][y][z]->Blockdata(this, x, y, z, this->triangles);
}
}
}
}
If more details or information is needed please just ask.