fix: center ground under chunks and align player spawn with chunk grid
checkpoint / checkpoint (push) Successful in 5m56s
checkpoint / checkpoint (push) Successful in 5m56s
This commit is contained in:
+70
-3
@@ -38,6 +38,7 @@ var _build_editor: InGameEditor = null
|
||||
|
||||
|
||||
var _stream_manager: ChunkStreamManager = null
|
||||
var _loaded_chunk_coords: Array[Vector3i] = []
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
@@ -75,11 +76,75 @@ func _setup_chunk_streaming() -> void:
|
||||
_stream_manager._load_chunk(Vector3i.ZERO)
|
||||
|
||||
|
||||
func _on_chunk_loaded(_coord: Vector3i, chunk_scene: Node) -> void:
|
||||
func _on_chunk_loaded(coord: Vector3i, chunk_scene: Node) -> void:
|
||||
if chunk_scene is ChunkScene:
|
||||
var cs := chunk_scene as ChunkScene
|
||||
if not cs.world_objects.is_empty() or not cs.tile_layers.is_empty():
|
||||
_hide_default_test_props()
|
||||
_hide_default_test_props()
|
||||
if not (coord in _loaded_chunk_coords):
|
||||
_loaded_chunk_coords.append(coord)
|
||||
_adjust_ground_and_spawn_for_chunks(cs)
|
||||
|
||||
|
||||
func _adjust_ground_and_spawn_for_chunks(cs: ChunkScene) -> void:
|
||||
var min_cx := 0
|
||||
var max_cx := 0
|
||||
var min_cy := 0
|
||||
var max_cy := 0
|
||||
for c in _loaded_chunk_coords:
|
||||
min_cx = mini(min_cx, c.x)
|
||||
max_cx = maxi(max_cx, c.x)
|
||||
min_cy = mini(min_cy, c.y)
|
||||
max_cy = maxi(max_cy, c.y)
|
||||
|
||||
var min_x := float(min_cx * Chunk.CHUNK_SIZE_X)
|
||||
var max_x := float((max_cx + 1) * Chunk.CHUNK_SIZE_X)
|
||||
var min_z := float(min_cy * Chunk.CHUNK_SIZE_Y)
|
||||
var max_z := float((max_cy + 1) * Chunk.CHUNK_SIZE_Y)
|
||||
|
||||
var center_x := (min_x + max_x) * 0.5
|
||||
var center_z := (min_z + max_z) * 0.5
|
||||
var size_x := maxf(40.0, (max_x - min_x) + 8.0)
|
||||
var size_z := maxf(40.0, (max_z - min_z) + 8.0)
|
||||
|
||||
var ground := get_node_or_null("Level/Ground") as StaticBody3D
|
||||
if ground != null:
|
||||
ground.position = Vector3(center_x, -0.5, center_z)
|
||||
var shape_node := ground.find_child("CollisionShape3D", true, false) as CollisionShape3D
|
||||
if shape_node != null:
|
||||
var box: BoxShape3D
|
||||
if shape_node.shape is BoxShape3D:
|
||||
box = (shape_node.shape as BoxShape3D).duplicate() as BoxShape3D
|
||||
else:
|
||||
box = BoxShape3D.new()
|
||||
box.size = Vector3(size_x, 1.0, size_z)
|
||||
shape_node.shape = box
|
||||
var mesh_node := ground.find_child("MeshInstance3D", true, false) as MeshInstance3D
|
||||
if mesh_node != null:
|
||||
var box_mesh: BoxMesh
|
||||
if mesh_node.mesh is BoxMesh:
|
||||
box_mesh = (mesh_node.mesh as BoxMesh).duplicate() as BoxMesh
|
||||
else:
|
||||
box_mesh = BoxMesh.new()
|
||||
box_mesh.size = Vector3(size_x, 1.0, size_z)
|
||||
mesh_node.mesh = box_mesh
|
||||
|
||||
var spawn_marker := get_node_or_null("Level/PlayerSpawn") as Node3D
|
||||
var found_spawn: Variant = null
|
||||
for obj in cs.world_objects:
|
||||
if obj.type == "spawn_point" or (obj.properties is Dictionary and obj.properties.get("catalog_id") == "spawn_point"):
|
||||
found_spawn = cs.global_position + Vector3(obj.position.x, 1.5, obj.position.y)
|
||||
break
|
||||
|
||||
if found_spawn != null:
|
||||
if spawn_marker != null:
|
||||
spawn_marker.global_position = found_spawn
|
||||
if not _aligned:
|
||||
_player.global_position = found_spawn
|
||||
elif spawn_marker != null and spawn_marker.global_position.is_equal_approx(Vector3(0, 1.5, 0)):
|
||||
var default_center := Vector3(16.0, 1.5, 16.0)
|
||||
spawn_marker.global_position = default_center
|
||||
if not _aligned:
|
||||
_player.global_position = default_center
|
||||
|
||||
|
||||
func _hide_default_test_props() -> void:
|
||||
@@ -194,6 +259,7 @@ func _close_build_mode() -> void:
|
||||
_player.set_process_unhandled_input(true)
|
||||
_player._refresh_mouse_mode()
|
||||
|
||||
_loaded_chunk_coords.clear()
|
||||
if _stream_manager == null:
|
||||
_setup_chunk_streaming()
|
||||
elif is_instance_valid(_stream_manager):
|
||||
@@ -273,6 +339,7 @@ func _leave_world() -> void:
|
||||
|
||||
## Close the ENet connection and stop it from calling us back mid-teardown.
|
||||
func _teardown_net() -> void:
|
||||
_loaded_chunk_coords.clear()
|
||||
if _stream_manager != null and is_instance_valid(_stream_manager):
|
||||
_stream_manager.clear_all_chunks()
|
||||
_stream_manager.queue_free()
|
||||
|
||||
Reference in New Issue
Block a user