diff options
author | Lucas Fryzek <lucas.fryzek@fryzekconcepts.com> | 2024-09-22 18:19:51 +0100 |
---|---|---|
committer | Lucas Fryzek <lucas.fryzek@fryzekconcepts.com> | 2024-09-22 18:19:51 +0100 |
commit | 599c8dd969ca3eec1767eaf3585ae9a32d23fa57 (patch) | |
tree | 3eae1c533d72413ce4b55c2da0a81593f4639c3b /scripts | |
parent | e9b2e264f767da4e630a515ae3217f3966be9ce6 (diff) |
bsp_level_generator: Generate level geometry manually
Don't use CSG geometry, this makes it easier to generate a collision
mesh, and in the future would make it easier to have player created
levels.
Level generation is much faster now as well.
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/bsp_level_generator.gd | 68 | ||||
-rw-r--r-- | scripts/enemy.gd | 2 |
2 files changed, 46 insertions, 24 deletions
diff --git a/scripts/bsp_level_generator.gd b/scripts/bsp_level_generator.gd index 87806e2..2243481 100644 --- a/scripts/bsp_level_generator.gd +++ b/scripts/bsp_level_generator.gd @@ -7,7 +7,9 @@ extends Node3D @export_category("Geometry Generator") ## Geometry generation config -@export var wall_thickness: float = 1 +@export var wall_thickness: float = 1.25 + +@onready var mesh: MeshInstance3D = $MeshInstance3D var min_room_size: int = min_dim * min_dim @@ -95,6 +97,8 @@ func generate_grid(map: BSPNode, grid: Array[Tile]): and grid[room_right.y * grid_width + room_right.x] == Tile.FLOOR \ and grid[door_pos.y * grid_width + door_pos.x] == Tile.WALL: have_door = true + + # Place grid for mesh grid[door_pos.y * grid_width + door_pos.x] = Tile.FLOOR door_pos[map.axis] -= 1 grid[door_pos.y * grid_width + door_pos.x] = Tile.FLOOR @@ -105,34 +109,37 @@ func generate_grid(map: BSPNode, grid: Array[Tile]): get_tree().quit() return -func generate_geo(grid: Array[Tile]): - var csg_root = CSGCombiner3D.new() +func generate_plane(array: Array, pos: Vector3, dim: Array[Vector3], normal: Vector3): + var index = len(array[Mesh.ARRAY_VERTEX]) + array[Mesh.ARRAY_VERTEX].append(wall_thickness*pos) + array[Mesh.ARRAY_VERTEX].append(wall_thickness*(pos+dim[0])) + array[Mesh.ARRAY_VERTEX].append(wall_thickness*(pos+dim[0]+dim[1])) + array[Mesh.ARRAY_VERTEX].append(wall_thickness*(pos+dim[1])) + + array[Mesh.ARRAY_NORMAL].append(normal) + array[Mesh.ARRAY_NORMAL].append(normal) + array[Mesh.ARRAY_NORMAL].append(normal) + array[Mesh.ARRAY_NORMAL].append(normal) + + array[Mesh.ARRAY_INDEX].append(index + 0) + array[Mesh.ARRAY_INDEX].append(index + 1) + array[Mesh.ARRAY_INDEX].append(index + 2) + array[Mesh.ARRAY_INDEX].append(index + 0) + array[Mesh.ARRAY_INDEX].append(index + 2) + array[Mesh.ARRAY_INDEX].append(index + 3) + +func generate_geo(grid: Array[Tile], array: Array): for y in range(grid_height): for x in range(grid_width): var tile = grid[y * grid_width + x] if tile == Tile.FLOOR: - var box = CSGBox3D.new() - box.size = Vector3(1.5, 0.1, 1.5) - box.position = 1.5*Vector3(x, 0, y) + 0.5 * box.size - csg_root.add_child(box) + generate_plane(array, Vector3(x, 0, y), [Vector3(1, 0, 0), Vector3(0, 0, 1)], Vector3.UP) elif tile == Tile.WALL: - var box = CSGBox3D.new() - box.size = Vector3(1.5, 2, 1.5) - box.position = 1.5*Vector3(x, 0, y) + 0.5 * box.size - csg_root.add_child(box) - - csg_root.use_collision = true - $NavigationRegion3D.add_child(csg_root) - - # We need to delay baking the nav mesh as - # the CSG won't be generated immediately - call_deferred("bake_nav") - -func bake_nav(): - print("Baking mesh") - $NavigationRegion3D.bake_navigation_mesh(false) - print("done baking") + generate_plane(array, Vector3(x, 2, y), [Vector3(0, 0, 1), Vector3(0, -2, 0)], Vector3.RIGHT) + generate_plane(array, Vector3(x, 2, y+1), [Vector3(1, 0, 0), Vector3(0, -2, 0)], Vector3.BACK) + generate_plane(array, Vector3(x+1, 2, y+1), [Vector3(0, 0, -1), Vector3(0, -2, 0)], Vector3.LEFT) + generate_plane(array, Vector3(x+1, 2, y), [Vector3(-1, 0, 0), Vector3(0, -2, 0)], Vector3.FORWARD) func _ready() -> void: var starting_axis = randi_range(0, 1) @@ -142,5 +149,18 @@ func _ready() -> void: var grid: Array[Tile] = [] grid.resize(grid_width * grid_height) grid.fill(Tile.WALL) + + var surface_array = [] + surface_array.resize(Mesh.ARRAY_MAX) + + surface_array[Mesh.ARRAY_VERTEX] = PackedVector3Array() + surface_array[Mesh.ARRAY_INDEX] = PackedInt32Array() + surface_array[Mesh.ARRAY_NORMAL] = PackedVector3Array() + generate_grid(map, grid) - generate_geo(grid) + generate_geo(grid, surface_array) + + mesh.mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, surface_array) + var tri_mesh = mesh.mesh.create_trimesh_shape() + $NavigationRegion3D/StaticBody3D/CollisionShape3D.shape = tri_mesh + $NavigationRegion3D.bake_navigation_mesh() diff --git a/scripts/enemy.gd b/scripts/enemy.gd index 6be60c7..1c4c063 100644 --- a/scripts/enemy.gd +++ b/scripts/enemy.gd @@ -62,6 +62,8 @@ func chase_nav_mesh(delta: float): var next_location = nav_agent.get_next_path_position() var new_velocity = (next_location - current_location).normalized() * speed + #print("Target is ", next_location) + # We only want to navigate on XZ plane new_velocity.y = 0 |