I’m having a problem with MapGeneration that i can’t work out.
So i have a ALevelGenerator
Class and Blueprint Implementation.
Inside the Class,
i have array of room’s allowed ( TArray <TSubclassOf<class ARoom>> genericRoom )
ARoom has a roomMesh a entrance and exit mesh for there possition and rotation,
Main detection point is if (room->roomMesh->IsOverlappingActor(roomtoSpawn) || roomtoSpawn->roomMesh->IsOverlappingActor(room))
This does not seem to be working as the image
and in BP i say how many rooms i want to generate.
so maxRooms = 15;
i have removed some code that’s not part of the problem
void ALevelGenerator::PostInitializeComponents()
{
Super::PostInitializeComponents();
spawnParams.Owner = this;
spawnParams.Instigator = Instigator;
// make sure the GenerateMap does not fail
while (!GenerateMap()) { }
}
bool ALevelGenerator::GenerateMap()
{
ARoom* lastRoom = nullptr;
TArray<int> blocked;
bool spawnedBossRoom = false;
ARoom* roomtoSpawn = GetWorld()->SpawnActor<ARoom>(startingRoom, this->GetActorLocation(), this->GetActorRotation(), spawnParams);
roomsIngame.Add(roomtoSpawn);
for (int i = 1; i < maxRooms; i++)
{
// holds a pointer to the room we're going to spawn
ARoom* roomtoSpawn = NULL;
// get the total number of room currently spawned
int roomsInGameCount = roomsIngame.Num();
// if we're at 0 we need the starting room
// pick a random index for a room
int randRoomIndex = FMath::FRandRange(0, genericRoom.Num());
// check room is not blocked
while (blocked.Contains(randRoomIndex)) {
randRoomIndex = FMath::FRandRange(0, genericRoom.Num());
}
// is this supposed to be the last room
if (roomsInGameCount == maxRooms-1) {
//Spawn Boss Room
roomtoSpawn = GetWorld()->SpawnActor<ARoom>(bossRoom, roomsIngame[i - 1]->roomMesh->GetSocketLocation("exit"), roomsIngame[i - 1]->GetActorRotation(), spawnParams);
spawnedBossRoom = true;
}
else {
// spawn random room
roomtoSpawn = GetWorld()->SpawnActor<ARoom>(getRandomRoom(randRoomIndex), roomsIngame[i - 1]->roomMesh->GetSocketLocation("exit"), roomsIngame[i - 1]->GetActorRotation(), spawnParams);
}
roomtoSpawn->AttachToActor(roomsIngame[i - 1], FAttachmentTransformRules::SnapToTargetIncludingScale,"exit");
/*Offset Room rotation to match doors*/
float dotProduct = FVector::DotProduct(roomsIngame[i - 1]->roomMesh->GetSocketLocation("exit"), roomtoSpawn->roomMesh->GetSocketLocation("entrence"));
if (dotProduct != 1) {
float rotOffset = roomsIngame[i - 1]->roomMesh->GetSocketRotation("exit").Yaw - roomtoSpawn->roomMesh->GetSocketRotation("entrence").Yaw;
FRotator nRotation = roomtoSpawn->GetActorRotation();
nRotation.Yaw = (nRotation.Yaw + rotOffset) + 180;
roomtoSpawn->SetActorRotation(nRotation);
}
/*Offset Room Location to match doors*/
FVector offset = roomsIngame[i - 1]->roomMesh->GetSocketLocation("exit") - roomtoSpawn->roomMesh->GetSocketLocation("entrence");
roomtoSpawn->SetActorLocation(roomtoSpawn->GetActorLocation() + offset);
roomtoSpawn->DetachRootComponentFromParent();
// get a lit of overlapping actors this should be empty for
// successfull room spawning
TArray<AActor*> overlappingActors;
for (ARoom* room : roomsIngame) {
bool shouldBreak = false;
if (roomtoSpawn->roomMesh->IsOverlappingActor(room))
{
if (spawnedBossRoom) { return false; }
// add it to block list
blocked.Add(randRoomIndex);
// if all rooms have been blocked we ■■■■■■ up start again
if (blocked.Num() == genericRoom.Num()) {
return false;
}
// remove this room it does not fit
roomtoSpawn->Destroy();
// set the loop back one
i--;
shouldBreak = true;
}
if (shouldBreak) { break; }
}
// room was added empty the block list
blocked.Empty();
// add room to our spawned room's array
roomsIngame.Add(roomtoSpawn);
}
return (roomsIngame.Num() == maxRooms);
}