Add crowd presentation, fix NPC navigation, refresh screenshots
NPC navigation (previously dead in the live game) - Only assign NavigationAgent3D.target_position when it changes: re-assigning every frame invalidated the path, so get_next_path_position() kept returning the current point and avatars never moved. - Follow the first path point that is closer to the destination than the avatars are. Nav points sit on the navmesh plane (y=0) while bodies stand at y~0.5, so the old 3D distance test always looked "already there"; path[0] is also the old start point, so a naive "far enough away" pick steered backwards and oscillated. - Fix fsm.state -> fsm.current_state in the idle-lifetime check. Crowd presentation - Aggressive behavior, visible weapons, and responder arrivals make idle bystanders stop and face the incident for 12 s; someone waiting at the entrance keeps focus. - Panic (mood >= 0.75) walks people away from the door at 2.4 m/s, then they despawn. - Wire reactions to EventBus.crowd_changed: CrowdSystem.apply_event() emits on the bus, not on its own `changed` signal (the first wiring received nothing). - Measured a 16-NPC entrance at ~1.2 ms/frame (824 fps, vsync off), so no LOD/culling. World and HUD - Skyline is now a ring of four alpha-scissored planes at 200 m instead of a single plane; PlaneMesh defaults to horizontal, which is why the backdrop rendered as a band overhead. Larger ground plane, mipmapped texture, scissor threshold 0.5 (0.3 left mip dashes in the sky), lifted albedo so the city is not pure black. - Flashlight aims straight ahead and lights the person/door instead of the ground. - Shorter HUD controls line so it stops overlapping itself. Tests, tooling, docs - Headless suite 98 -> 105 (new test_crowd_presentation.gd, 7 tests). - New smoke_crowd.gd: rubbernecking, panic, and flee-target sanity. - capture_screenshots.gd starts a shift from the venue menu and stages the night set properly; all six README screenshots regenerated. - README, TODO/DONE (crowd section moved), MEMORY updated. Version 0.2.4.
This commit is contained in:
1 parent
f5ad1642b5
commit
71b0b53705
21 files changed
+512
-60
No files matched your search
+38
-16
@@ -57,9 +57,11 @@ func _add_box(parent: Node3D, size: Vector3, pos: Vector3, color: Color, cast_sh
|
||||
func _build_ground() -> void:
|
||||
var ground := StaticBody3D.new()
|
||||
ground.name = "Ground"
|
||||
_add_box(root, Vector3(160, 0.5, 160), Vector3(0, -0.25, 20), Color(0.22, 0.24, 0.26))
|
||||
# Large enough that the ground meets the distant skyline ring (no gap of sky
|
||||
# under the buildings when looking down the boulevard).
|
||||
_add_box(root, Vector3(500, 0.5, 500), Vector3(0, -0.25, 20), Color(0.22, 0.24, 0.26))
|
||||
var col := BoxShape3D.new()
|
||||
col.size = Vector3(160, 1, 160)
|
||||
col.size = Vector3(500, 1, 500)
|
||||
var shape_owner := ground.create_shape_owner(ground)
|
||||
ground.shape_owner_add_shape(shape_owner, col)
|
||||
root.add_child(ground)
|
||||
@@ -165,29 +167,49 @@ func _build_navmesh() -> void:
|
||||
root.add_child(region)
|
||||
|
||||
func _build_skyline_backdrop() -> void:
|
||||
## Skyline silhouette backdrop behind the building. The texture has a
|
||||
## transparent sky, so only the building silhouettes show; the material must
|
||||
## be set up for alpha or the plane renders as an opaque slab (ADR/TODO).
|
||||
## Distant skyline surrounding the block. The texture's sky is transparent
|
||||
## (alpha scissor), so only building silhouettes show. Four planes form a
|
||||
## ring: a single plane placed behind the building reads as a floating black
|
||||
## band from the sidewalk.
|
||||
var backdrop := Node3D.new()
|
||||
backdrop.name = "SkylineBackdrop"
|
||||
var plane := MeshInstance3D.new()
|
||||
var mesh := PlaneMesh.new()
|
||||
mesh.size = Vector2(240, 60) # wide, low horizon
|
||||
plane.mesh = mesh
|
||||
var mat := StandardMaterial3D.new()
|
||||
mat.albedo_texture = T_SKYLINE
|
||||
mat.texture_repeat = true
|
||||
mat.uv1_scale = Vector3(2.0, 1.0, 1.0)
|
||||
mat.uv1_scale = Vector3(3.0, 1.0, 1.0)
|
||||
mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_SCISSOR
|
||||
mat.alpha_scissor_threshold = 0.3
|
||||
mat.alpha_scissor_threshold = 0.5
|
||||
mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
|
||||
mat.cull_mode = BaseMaterial3D.CULL_DISABLED
|
||||
plane.material_override = mat
|
||||
plane.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
|
||||
plane.position = Vector3(0, 18, -60) # behind and above the building
|
||||
backdrop.add_child(plane)
|
||||
root.add_child(backdrop)
|
||||
# Unshaded silhouettes read as pure black at 255-scale; lift the albedo so the
|
||||
# distant skyline sits closer to a hazy daytime city.
|
||||
mat.albedo_color = Color(2.6, 2.7, 3.0, 1.0)
|
||||
_skyline_mat = mat
|
||||
var mesh := PlaneMesh.new()
|
||||
# PlaneMesh defaults to a horizontal (XZ) plane; the skyline must stand up.
|
||||
mesh.orientation = PlaneMesh.FACE_Z
|
||||
mesh.size = Vector2(400, 60)
|
||||
# Far enough that the skyline reads as background and its top edge stays out
|
||||
# of the middle of the sky.
|
||||
const DIST := 200.0
|
||||
# The texture keeps its buildings in the lower part of the image, so the plane
|
||||
# center sits at half its height: the building bases meet the ground.
|
||||
const CENTER_Y := 30.0
|
||||
var placements := [
|
||||
[Vector3(0, CENTER_Y, -DIST), 0.0],
|
||||
[Vector3(0, CENTER_Y, DIST), 0.0],
|
||||
[Vector3(-DIST, CENTER_Y, 0), PI / 2.0],
|
||||
[Vector3(DIST, CENTER_Y, 0), PI / 2.0],
|
||||
]
|
||||
for placement in placements:
|
||||
var plane := MeshInstance3D.new()
|
||||
plane.mesh = mesh
|
||||
plane.material_override = mat
|
||||
plane.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
|
||||
plane.position = placement[0]
|
||||
plane.rotation.y = placement[1]
|
||||
backdrop.add_child(plane)
|
||||
root.add_child(backdrop)
|
||||
|
||||
var _skyline_mat: StandardMaterial3D = null
|
||||
|
||||
|
||||
Reference in new issue
Block a user