So I haven’t bothered setting the Material yet. I just want to make sure the fences actually spawn and move properly. So far, nothing I have done has made them visible.
Here are the constructor and AssignMesh methods for the Fence obstacle. Note that the spawner object instantiates new fence objects, and calls the AssignMesh() method for each immediately after creating them.
AFenceObstacle::AFenceObstacle()
{
// 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;
//Create the box component for collisions
BoxComponent = CreateDefaultSubobject<UBoxComponent>(TEXT("CollisionBox"));
check(BoxComponent != nullptr);
//Create a visible mesh for the fence. CreateDefaultSubobject cannot be called outside of constructors
VisibleMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("VisibleMesh"));
if (VisibleMesh) {
VisibleMesh->SetupAttachment(GetRootComponent());
}
}
//Assigns the appropriate mesh after creation (called externally)
void AFenceObstacle::AssignMesh() {
if (HeightMarker > 0 && HeightMarker < 9) {
//Assign the appropriate mesh to the fence based on the assigned HeightMarker
auto const Path = FString::Printf(TEXT("/Game/Meshes/sm_obstacle_fence_size_%i.sm_obstacle_fence_size_%i"), HeightMarker, HeightMarker);
auto Mesh = LoadObject<UStaticMesh>(nullptr, TEXT("FenceMesh"), *Path);
if (Mesh) {
VisibleMesh->SetStaticMesh(Mesh);
}
}
else {
//If an erroneous HeightMarker value was assigned, show that in a debug message
check(GEngine != nullptr);
//Display a debug message for five seconds
//The -1 "Key" vale argument prevents the message from being updated or refreshed.
auto const err_msg = FString::Printf(TEXT("AssignMesh: Invalid fence height value: %i"), HeightMarker);
GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, err_msg);
}
}
For reference, this is the relevant code in the spawner object.
//Increment/Decrement timers, spawn objects
if (SpawnTimer <= 0.0f) {
//Spawn a new fence obstacle with appropriate height
int FenceHeight = FMath::RandRange(1, 8);
AFenceObstacle* NewFence = World->SpawnActor<AFenceObstacle>(SpawnParams);
FVector SpawnLocation = FVector(300.0f, 0.0f, 0.0f);
NewFence->SetActorLocation(SpawnLocation);
NewFence->ObstacleSpeed = ObstacleSpeed;
NewFence->HeightMarker = FenceHeight;
NewFence->AssignMesh();
//DEBUG: Show a prompt indicating that a new fence has been created
FVector loc = NewFence->GetActorLocation();
auto const debug_msg = FString::Printf(TEXT("New fence %i spawned. Height = %i. Spd = %f. X = %f. Y = %f. Z = %f"), FenceIndex, FenceHeight, ObstacleSpeed, loc.X, loc.Y, loc.Z);
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, debug_msg);
//GUBED
Fences[FenceIndex] = NewFence;
FenceIndex++;
if (FenceIndex >= 4) {
FenceIndex = 0;
}
SpawnTimer = 5.0f; //<-- This will be modified later to depend on TimeElapsed
}
else {
SpawnTimer -= DeltaTime;
}