My code for creating rooms out of voxels isn't working; rooms keep colliding? Code included

Viewed 37

I have some code that is supposed to create a grid of voxels, and then rooms out of those voxels. However, a lot of the rooms still overlap, even when I wrote code specifically to prevent this from happening. Would anybody be able to tell me what's going?

I'm using an out variable for the first time, and I think that's part of the issues.

Basically, the code is supposed to create a list of voxels to turn into a room, turn them into a room, and repeat for the total number of rooms. If a voxel in the list is found to already be a room, it should clear the list and not create a room.

All the relevant code is below, you should be able to plug this into a new Unity project and see for yourself everything, complete with Gizmos.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum VoxelType{
    Undefined = 0,
    OpenRoom,
    OpenHall,
    Wall,
    Buffer,
}

[System.Serializable]
public class Voxel {
    public Vector3 position;
    public VoxelType voxelType;
    public int voxelX;
    public int voxelY;
    
    public Voxel(Vector3 newPosition, int x, int y, VoxelType newType = 0){
        position = newPosition;
        voxelType = newType;

        voxelX = x;
        voxelY = y;
    }
}

public class VoxelManager : MonoBehaviour
{
    public Vector2 mapSize;
    
    public float voxelSize;

    public int rooms;
    public int maxRoomHeight;
    public int minRoomHeight;
    public int maxRoomWidth;
    public int minRoomWidth;

    List<Voxel> voxels = new List<Voxel>();
    
    void OnDrawGizmosSelected(){
        foreach(Voxel voxel in voxels){
            if (voxel.voxelType == VoxelType.OpenRoom){
                Gizmos.color = Color.red;
            } else { 
                Gizmos.color = Color.blue;
            }

            switch (voxel.voxelType){
                case VoxelType.Undefined:
                    Gizmos.color = Color.blue;
                    break;
                case VoxelType.Wall:
                    Gizmos.color = Color.magenta;
                    break;
                case VoxelType.OpenRoom:
                    Gizmos.color = Color.red;
                    break;
            }
            Gizmos.DrawCube(voxel.position, Vector3.one * voxelSize *.995f);
        }
    }

    void Start(){
        voxelSpawn = prefab;

        for(int i = 0; i < mapSize.x; i++){
            for (int j = 0; j < mapSize.y; j++){
                float xLocation = voxelSize * i;
                float zLocation = voxelSize * j;

                float centerXLocation = (xLocation - (mapSize.x * voxelSize) / 2f) + voxelSize / 2f;
                float centerZLocation = (zLocation - (mapSize.y * voxelSize) / 2f) + voxelSize / 2f;

                string voxelName = i + "x" + j;

                Vector3 center = new Vector3(centerXLocation, voxelSize / 2, centerZLocation);
                
                voxels.Add(new Voxel(center, i, j));
            }
        }

        for (int i = 0; i < rooms; i++){
            List<Voxel> roomVoxels = new List<Voxel>();

            int generatedHeight = Random.Range(minRoomHeight, maxRoomHeight);
            int generatedWidth = Random.Range(minRoomWidth, maxRoomWidth);
            
            int horizontalRoomIndex = Random.Range(0, ((int)mapSize.x));
            int verticalRoomIndex = Random.Range(0, ((int)mapSize.y));
            
            bool occupied = false;
                       
            foreach(Voxel voxel in voxels){
                if(voxel.voxelX == horizontalRoomIndex && voxel.voxelY == verticalRoomIndex){
                    for (int j = 0; j < generatedHeight; j++){
                        for (int k = 0; k < generatedWidth; k++){
                            roomVoxels.Add(GetVoxelAtPosition(horizontalRoomIndex + j, verticalRoomIndex + k, out occupied));
                        }
                    }
                }
            }

            if(occupied == true){
                Debug.Log("Room occupied; unable to create! Clearing the current list to be turned into a room!");
                roomVoxels.Clear();
                i--;
            } else { 
                Debug.Log("Making a room!");
                foreach(Voxel roomVoxel in roomVoxels){
                    roomVoxel.voxelType = VoxelType.OpenRoom;
                }
            }
        }
    }

    Voxel GetVoxelAtPosition(int x, int y, out bool occupied){
        foreach(Voxel voxel in voxels){
            if(voxel.voxelX == x && voxel.voxelY == y){
                if (voxel.voxelType == VoxelType.Undefined){
                    occupied = false;
                    return voxel;
                } else {
                    Debug.Log("Voxel occupied!");
                    occupied = true;
                    return voxels[0];
                }   
            }
        }

        occupied = true;
        return voxels[0];
    }
}
0 Answers
Related