Working on a dungeon generator, so far I’ve managed to spawn corridors of different lengths and intersections that behave as expected.
Now I think I have to figure out a way to remove overlaps.
I know it’s not very impressive but I’m new to scripting and happy that I’ve gotten this far.
This night was spent figuring out a way to generate only one or two new corridors based on what intersection was there.
Couldn´t get it to work by names because of instancing I think. So I solved it by looking at how many children the intersection has. t-sections have more than left or right turns.
Really neat! Is this for a rogue-like?
Looks neat! Do the colors denote any meaning, or is that just a stylistic choice? Either way, it looks very cool. What are you going to do once you’ve managed to get the overlaps working the way you want?
I find programming procedural things are very satisfying because small changes can really change how things turn out.
I’m still trying to solve this intersection problem.
I want to check if the tiles are intersecting after placing it, if it intersects it should be removed.
I’ve tried with Area3D and collision shape.
And also direct_space_state
But the issue seems to be that all the collision detection is made after instantiation, even with direct_space_state
So it places all the tiles and then I get signaled about intersections.
Any help would be appreciated
extends Node
@onready var tile5 = load("res://assets/3D/Floor05.tscn")
@onready var tile10 = load("res://assets/3D/Floor10.tscn")
@onready var tile15 = load("res://assets/3D/Floor15.tscn")
@onready var cross = load("res://assets/3D/FloorT.tscn")
@onready var lTurn = load("res://assets/3D/FloorL.tscn")
@onready var rTurn = load("res://assets/3D/FloorR.tscn")
var corridorList = [tile5, tile10, tile15]
var intersectionList = [cross, lTurn, rTurn]
var corridorArray = []
var intersectionArray = []
var intersected = false
func _ready():
corridorList = [tile5, tile10, tile15]
intersectionList = [cross, lTurn, rTurn]
# Place first corridor at base marker
var baseMarker = get_node("Floor05/Marker3D")
var tileInstance = corridorList.pick_random().instantiate()
add_child(tileInstance)
corridorArray.append(tileInstance)
tileInstance.position = baseMarker.global_position
# Place intersection at corridor marker
placeIntersectionAtMarker(corridorArray[0].get_node("Marker3D"))
corridorArray.clear()
# Repeat the process
while get_child_count() < 50:
for i in intersectionArray:
#T sections will have more children than R and L sections
if i.get_child_count() == 3:
placeCorridorAtMarker(i.get_node("MarkerA"))
placeCorridorAtMarker(i.get_node("MarkerB"))
elif i.get_child_count() == 2:
placeCorridorAtMarker(i.get_node("MarkerA"))
intersectionArray.clear()
for i in corridorArray:
placeIntersectionAtMarker(i.get_node("Marker3D"))
corridorArray.clear()
func placeIntersectionAtMarker(marker):
intersectionList = [cross, lTurn, rTurn]
var intersectionInstance = intersectionList.pick_random().instantiate()
add_child(intersectionInstance)
intersectionInstance.position = marker.global_position
intersectionInstance.rotation = marker.global_rotation
#Check for overlaps before finalizing
if is_tile_overlapping(intersectionInstance):
print("Overlap detected, removing the new tile.")
intersectionInstance.queue_free()
else:
print("No overlap, tile added successfully.")
intersectionArray.append(intersectionInstance)
func placeCorridorAtMarker(marker):
corridorList = [tile5, tile10, tile15]
var tileInstance = corridorList.pick_random().instantiate()
add_child(tileInstance)
tileInstance.position = marker.global_position
tileInstance.rotation = marker.global_rotation
#Check for overlaps before finalizing
if is_tile_overlapping(tileInstance):
print("Overlap detected, removing the new tile.")
tileInstance.queue_free()
else:
print("No overlap, tile added successfully.")
corridorArray.append(tileInstance)
func is_tile_overlapping(tile_instance) -> bool:
# Find the CollisionShape3D within the tile instance
var collision_shape = tile_instance.get_node("MeshInstance3D/Area3D/CollisionShape3D")
if not collision_shape:
print("Error: No CollisionShape3D found in tile!")
return true # Assume overlap if there's no collision shape
# Use the CollisionShape3D's shape and global transform for the test
var shape = collision_shape.shape
if not shape:
print("Error: CollisionShape3D has no shape!")
return true # Treat as overlapping by default (or false if you'd prefer)
var transform = collision_shape.global_transform
# Debug: Print transform and shape info
print("Tile transform: ", transform)
print("Tile shape: ", shape)
# Access the direct space state
var space_state = get_viewport().get_world_3d().direct_space_state
#prepare the physicsShapeQueryParameters3D
var query = PhysicsShapeQueryParameters3D.new()
query.shape = shape
query.transform = transform
query.margin = 0.1 # Small margin to handle precision issues
var result = space_state.intersect_shape(query, 32) # Max 32 results
if result.size() > 0:
print("Overlap detected! Result: ", result)
return true # Overlap detected
else:
print("No overlap, tile added successfully.")
return false # No overlap
https://youtu.be/Drqu_lYzzf0
youtube video
Wanted to give an update on my dungeon progress.
I’ve made a character and an enemy
They have animations and there is a selection system and system for dealing and recieving damage.
checking for tile intersections is now solved with just grid positions, before I used Area 3D.
Next step is to make the dungeon look a little more interesting. And introducing the concept of doors.