Loose shopping trolleys in the Woolies carpark
18 kg of chrome chaos each: procedural basket + handle + castors on a low-friction RigidBody, so they roll away when nudged and FLY when hit at speed. Four strays around every trolley bay plus five rogues claiming parking spots, as is tradition. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
52f7705e13
commit
30d5cfd846
@ -46,6 +46,12 @@ func _ready() -> void:
|
||||
_planter_island(Vector3(x, 0, -60.0 + j * 30.0), rng)
|
||||
for p in [Vector3(-52, 0, 44), Vector3(52, 0, 44), Vector3(-52, 0, -46)]:
|
||||
_trolley_bay(p)
|
||||
for i in 4: # strays that never made it back to the bay
|
||||
_trolley(p + Vector3(rng.randf_range(-7.0, 7.0), 0, rng.randf_range(-6.0, 6.0)),
|
||||
rng.randf() * TAU)
|
||||
for i in 5: # rogue trolleys claiming parking spots, as is tradition
|
||||
_trolley(Vector3(rng.randf_range(-60.0, 60.0), 0, rng.randf_range(-40.0, 40.0)),
|
||||
rng.randf() * TAU)
|
||||
_race_path()
|
||||
|
||||
func _mat(tex: String, scale: float, rough := 0.9) -> StandardMaterial3D:
|
||||
@ -179,6 +185,64 @@ func _trolley_bay(pos: Vector3) -> void:
|
||||
for j in 5: # the trolleys themselves
|
||||
_slab(pos + Vector3(0, 0.5, -3.2 + j * 1.6), Vector3(0.9, 1.0, 1.2), steel, false)
|
||||
|
||||
func _trolley(pos: Vector3, yaw: float) -> void:
|
||||
## A loose shopping trolley: 18 kg of chrome chaos. Light enough to FLY when
|
||||
## clipped at speed, low-friction so it rolls away like the real thing.
|
||||
var b := RigidBody3D.new()
|
||||
b.mass = 18.0
|
||||
var pm := PhysicsMaterial.new()
|
||||
pm.friction = 0.25
|
||||
pm.bounce = 0.25
|
||||
b.physics_material_override = pm
|
||||
var cs := CollisionShape3D.new()
|
||||
var bs := BoxShape3D.new()
|
||||
bs.size = Vector3(0.58, 0.95, 0.92)
|
||||
cs.shape = bs
|
||||
cs.position = Vector3(0, 0.5, 0)
|
||||
b.add_child(cs)
|
||||
var steel := _flat(Color(0.62, 0.63, 0.66), 0.35)
|
||||
steel.metallic = 0.7
|
||||
# basket: floor + four walls, wider at the top like the real thing
|
||||
var basket := [
|
||||
[Vector3(0, 0.42, 0), Vector3(0.50, 0.03, 0.84)], # floor
|
||||
[Vector3(0, 0.66, 0.44), Vector3(0.54, 0.45, 0.03)], # back
|
||||
[Vector3(0, 0.66, -0.42), Vector3(0.50, 0.45, 0.03)], # front
|
||||
[Vector3(0.27, 0.66, 0), Vector3(0.03, 0.45, 0.86)], # right
|
||||
[Vector3(-0.27, 0.66, 0), Vector3(0.03, 0.45, 0.86)], # left
|
||||
]
|
||||
for spec in basket:
|
||||
var mi := MeshInstance3D.new()
|
||||
var bm := BoxMesh.new()
|
||||
bm.size = spec[1]
|
||||
bm.material = steel
|
||||
mi.mesh = bm
|
||||
mi.position = spec[0]
|
||||
b.add_child(mi)
|
||||
var handle := MeshInstance3D.new()
|
||||
var hm := BoxMesh.new()
|
||||
hm.size = Vector3(0.58, 0.04, 0.04)
|
||||
hm.material = steel
|
||||
handle.mesh = hm
|
||||
handle.position = Vector3(0, 0.97, 0.50)
|
||||
b.add_child(handle)
|
||||
for sx in [-0.22, 0.22]:
|
||||
for sz in [-0.36, 0.36]:
|
||||
var c := MeshInstance3D.new()
|
||||
var cm := CylinderMesh.new()
|
||||
cm.top_radius = 0.05
|
||||
cm.bottom_radius = 0.05
|
||||
cm.height = 0.04
|
||||
cm.radial_segments = 8
|
||||
cm.material = _flat(Color(0.12, 0.12, 0.13), 0.7)
|
||||
c.mesh = cm
|
||||
c.rotation_degrees = Vector3(0, 0, 90)
|
||||
c.position = Vector3(sx, 0.05, sz)
|
||||
b.add_child(c)
|
||||
add_child(b)
|
||||
b.position = pos + Vector3.UP * 0.05
|
||||
b.rotate_y(yaw)
|
||||
b.sleeping = true
|
||||
|
||||
func _race_path() -> void:
|
||||
# perimeter loop road around the parking rows -- race line + traffic route
|
||||
var path := Path3D.new()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user