feat: parked cars across the city (Kenney Car Kit, CC0)
Streets are now populated: seeded parking lanes hug the curbs of every N-S street with sedans, taxis, vans, SUVs, hatchbacks, delivery trucks and the occasional police car (~100+ across the city). - Wheels attach at the models' wheel-socket empties at spawn - Metal-tagged box colliders: cars are cover that sounds like cover - Toonified + darkened base tint (kit albedo clips under the map light) with per-car hue jitter for varied paint jobs - Slight rotation jitter so parking reads natural, not stamped Verified via street capture (colored cars parked down the avenue, no clipping/glow); movement 11/11, smoke 0 failures, acoustics ALL PASSED. Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Fable 5
parent
04d91dea31
commit
56db9eea59
@@ -270,6 +270,7 @@ func _build_geometry() -> void:
|
||||
_build_rail_line()
|
||||
_build_streets()
|
||||
_build_avenues()
|
||||
_build_parked_cars()
|
||||
|
||||
if _spawn_points.is_empty():
|
||||
_spawn_points.append(Vector3(0, 2, 0))
|
||||
@@ -665,6 +666,59 @@ func _build_avenues() -> void:
|
||||
Vector3(x, 0, z2), 0.0 if side > 0 else 180.0, lamp_scale)
|
||||
|
||||
|
||||
# ── Parked cars (Kenney Car Kit) ─────────────────────────────────────────────
|
||||
|
||||
const CAR_KEYS := ["sedan", "sedan", "taxi", "van", "suv", "hatchback-sports",
|
||||
"delivery", "sedan-sports", "police"]
|
||||
const CAR_SCALE := 1.8
|
||||
|
||||
## A parked car: metal-tagged collider, kit body, wheels attached to the
|
||||
## model's wheel sockets, slight per-car tint.
|
||||
func _parked_car(pos: Vector3, yaw_deg: float) -> void:
|
||||
var key: String = CAR_KEYS[_rng.randi() % CAR_KEYS.size()]
|
||||
var body := StaticBody3D.new()
|
||||
body.name = "Car_%d" % _rng.randi()
|
||||
body.set_meta("acoustic_material", "metal")
|
||||
add_child(body)
|
||||
body.global_position = pos
|
||||
body.rotation_degrees.y = yaw_deg + _rng.randf_range(-3.0, 3.0)
|
||||
var shape := CollisionShape3D.new()
|
||||
var bs := BoxShape3D.new()
|
||||
bs.size = Vector3(2.8, 2.6, 5.0)
|
||||
shape.shape = bs
|
||||
shape.position = Vector3(0, 1.3, 0)
|
||||
body.add_child(shape)
|
||||
|
||||
var inst: Node3D = _kit_scene_at("res://assets/props/cars/" + key + ".glb").instantiate()
|
||||
inst.scale = Vector3.ONE * CAR_SCALE
|
||||
inst.position.y = 0.55 # wheel contact at ground after scaling
|
||||
body.add_child(inst)
|
||||
var wheel_scene := _kit_scene_at("res://assets/props/cars/wheel-default.glb")
|
||||
for n in inst.find_children("wheel*", "Node3D", true, false):
|
||||
if n.get_child_count() == 0 and not (n is MeshInstance3D):
|
||||
var wheel: Node3D = wheel_scene.instantiate()
|
||||
n.add_child(wheel)
|
||||
LevelMaterials.apply_toon_recursive(inst, 0.0)
|
||||
# Darken under the map lighting (kit albedo clips) + per-car hue
|
||||
_tint_recursive(inst, Color(0.62, 0.62, 0.66) * Color(1, 1, 1).lerp(Color.from_hsv(_rng.randf(), 0.6, 1.0), 0.35))
|
||||
|
||||
|
||||
## Seeded parking lanes hugging the curbs of the N-S streets.
|
||||
func _build_parked_cars() -> void:
|
||||
for x in _street_lines():
|
||||
for row in GRID:
|
||||
_rng.seed = hash(Vector2i(int(x), row)) + 913
|
||||
if _rng.randf() < 0.45:
|
||||
continue
|
||||
var z_base := (float(row) - float(GRID - 1) * 0.5) * PITCH
|
||||
var cars := 1 + _rng.randi() % 3
|
||||
for i in cars:
|
||||
var side := 1.0 if _rng.randi() % 2 == 0 else -1.0
|
||||
var cx := x + side * (ROAD_W * 0.5 - 1.8)
|
||||
var cz := z_base + _rng.randf_range(-18.0, 18.0)
|
||||
_parked_car(Vector3(cx, 0.02, cz), 0.0 if _rng.randi() % 2 == 0 else 180.0)
|
||||
|
||||
|
||||
func _kit_prop_path(path: String, pos: Vector3, yaw_deg: float, scale_f: float) -> void:
|
||||
var inst: Node3D = _kit_scene_at(path).instantiate()
|
||||
inst.scale = Vector3.ONE * scale_f
|
||||
|
||||
Reference in New Issue
Block a user