From 7c88e8371d4bf4ce008169d6651a45b556cd4f53 Mon Sep 17 00:00:00 2001 From: Monster Robot Party Date: Sat, 4 Jul 2026 00:39:46 +1000 Subject: [PATCH] Bring in real store art: Monster Robot Party racks, crates, records - game/assets/store/{rack,crate,record}.glb from the 3D-STORE library - _glb_piece(): instances a GLB as a Smashable's visual, auto-fits a box collider to the mesh AABB, and drops it flush to the floor (no hardcoded dims) - _build_rack now assembles two smashable racks + crates of records on the floor - cascade preserved: smashing a crate spills the records stacked on it Co-Authored-By: Claude Opus 4.8 --- assets/store/crate.glb | Bin 0 -> 57332 bytes assets/store/crate.glb.import | 45 ++++++++++++++ assets/store/rack.glb | Bin 0 -> 22620 bytes assets/store/rack.glb.import | 45 ++++++++++++++ assets/store/record.glb | Bin 0 -> 23160 bytes assets/store/record.glb.import | 45 ++++++++++++++ scripts/Main.gd | 109 +++++++++++++++++++++++---------- 7 files changed, 212 insertions(+), 32 deletions(-) create mode 100644 assets/store/crate.glb create mode 100644 assets/store/crate.glb.import create mode 100644 assets/store/rack.glb create mode 100644 assets/store/rack.glb.import create mode 100644 assets/store/record.glb create mode 100644 assets/store/record.glb.import diff --git a/assets/store/crate.glb b/assets/store/crate.glb new file mode 100644 index 0000000000000000000000000000000000000000..b47998607d2115712223838286642b9ffb27ca7f GIT binary patch literal 57332 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 J=l9M({~tP_sB8cL literal 0 HcmV?d00001 diff --git a/assets/store/crate.glb.import b/assets/store/crate.glb.import new file mode 100644 index 0000000..5605c14 --- /dev/null +++ b/assets/store/crate.glb.import @@ -0,0 +1,45 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://cu5trptulqcnq" +path="res://.godot/imported/crate.glb-24cac64f400a7a779f7206f210a4dd2a.scn" + +[deps] + +source_file="res://assets/store/crate.glb" +dest_files=["res://.godot/imported/crate.glb-24cac64f400a7a779f7206f210a4dd2a.scn"] + +[params] + +nodes/root_type="" +nodes/root_name="" +nodes/root_script=null +mesh_library/use_node_names_as_mesh_names=false +array_mesh/deduplicate_surfaces=true +nodes/apply_root_scale=true +nodes/root_scale=1.0 +nodes/import_as_skeleton_bones=false +nodes/use_name_suffixes=true +nodes/use_node_type_suffixes=true +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +meshes/force_disable_compression=false +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +animation/import_rest_as_RESET=false +import_script/path="" +materials/extract=0 +materials/extract_format=0 +materials/extract_path="" +_subresources={} +gltf/naming_version=2 +gltf/embedded_image_handling=1 +gltf/texture_map_mode=1 diff --git a/assets/store/rack.glb b/assets/store/rack.glb new file mode 100644 index 0000000000000000000000000000000000000000..3e004dc0906ff39efafa1c3facd3423676803f67 GIT binary patch literal 22620 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 N`@)#&p_^OK`2~_X$9Dh# literal 0 HcmV?d00001 diff --git a/assets/store/rack.glb.import b/assets/store/rack.glb.import new file mode 100644 index 0000000..be9206a --- /dev/null +++ b/assets/store/rack.glb.import @@ -0,0 +1,45 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://bhtt5qprxj00t" +path="res://.godot/imported/rack.glb-0e5d76da917de3ede0eb2963da764fe8.scn" + +[deps] + +source_file="res://assets/store/rack.glb" +dest_files=["res://.godot/imported/rack.glb-0e5d76da917de3ede0eb2963da764fe8.scn"] + +[params] + +nodes/root_type="" +nodes/root_name="" +nodes/root_script=null +mesh_library/use_node_names_as_mesh_names=false +array_mesh/deduplicate_surfaces=true +nodes/apply_root_scale=true +nodes/root_scale=1.0 +nodes/import_as_skeleton_bones=false +nodes/use_name_suffixes=true +nodes/use_node_type_suffixes=true +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +meshes/force_disable_compression=false +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +animation/import_rest_as_RESET=false +import_script/path="" +materials/extract=0 +materials/extract_format=0 +materials/extract_path="" +_subresources={} +gltf/naming_version=2 +gltf/embedded_image_handling=1 +gltf/texture_map_mode=1 diff --git a/assets/store/record.glb b/assets/store/record.glb new file mode 100644 index 0000000000000000000000000000000000000000..80a91657fb28ab7f18e57545be79a09f0815b5dc GIT binary patch literal 23160 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 SuUD`4?G{+YIILqFEdCd&ZJ9R! literal 0 HcmV?d00001 diff --git a/assets/store/record.glb.import b/assets/store/record.glb.import new file mode 100644 index 0000000..bff7483 --- /dev/null +++ b/assets/store/record.glb.import @@ -0,0 +1,45 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://b1hpf4j763ie0" +path="res://.godot/imported/record.glb-adf950a1184dabfc3a04addc4e1583a7.scn" + +[deps] + +source_file="res://assets/store/record.glb" +dest_files=["res://.godot/imported/record.glb-adf950a1184dabfc3a04addc4e1583a7.scn"] + +[params] + +nodes/root_type="" +nodes/root_name="" +nodes/root_script=null +mesh_library/use_node_names_as_mesh_names=false +array_mesh/deduplicate_surfaces=true +nodes/apply_root_scale=true +nodes/root_scale=1.0 +nodes/import_as_skeleton_bones=false +nodes/use_name_suffixes=true +nodes/use_node_type_suffixes=true +meshes/ensure_tangents=true +meshes/generate_lods=true +meshes/create_shadow_meshes=true +meshes/light_baking=1 +meshes/lightmap_texel_size=0.2 +meshes/force_disable_compression=false +skins/use_named_skins=true +animation/import=true +animation/fps=30 +animation/trimming=false +animation/remove_immutable_tracks=true +animation/import_rest_as_RESET=false +import_script/path="" +materials/extract=0 +materials/extract_format=0 +materials/extract_path="" +_subresources={} +gltf/naming_version=2 +gltf/embedded_image_handling=1 +gltf/texture_map_mode=1 diff --git a/scripts/Main.gd b/scripts/Main.gd index 2e6aa73..0800c65 100644 --- a/scripts/Main.gd +++ b/scripts/Main.gd @@ -74,42 +74,87 @@ func _setup_world() -> void: _world.name = "World" add_child(_world) -# ---------------------------------------------------------------- the rack -# One frame (frozen) holding shelves; on each shelf, crates; in each crate, -# cardboard jackets standing up with brittle vinyl records tucked between them. +# ---------------------------------------------------------------- the store +# Real Monster Robot Party assets: wooden racks (frozen backdrop you can smash) and +# crates of records in front. Colliders auto-size to each GLB's mesh AABB and every +# piece is dropped so its bottom rests exactly on the floor — no hardcoded dimensions. +const RACK_GLB := "res://assets/store/rack.glb" +const CRATE_GLB := "res://assets/store/crate.glb" +const RECORD_GLB := "res://assets/store/record.glb" + func _build_rack(origin: Vector3) -> void: - var shelf_ys := [0.45, 1.15] + # two racks form a smashable back wall of the booth + _glb_piece(RACK_GLB, "wood", Vector2(origin.x - 0.95, origin.z - 0.7), true) + _glb_piece(RACK_GLB, "wood", Vector2(origin.x + 0.95, origin.z - 0.7), true) - # 4 posts (frozen wood) — the primary supports for BOTH shelves. - var posts: Array[Smashable] = [] - for sx in [-0.62, 0.62]: - for sz in [-0.28, 0.28]: - posts.append(_piece("wood", Vector3(0.06, 1.5, 0.06), - origin + Vector3(sx, 0.75, sz), true)) + # crates of records on the floor in front, in two rows + var spots := [ + Vector2(-0.8, 0.5), Vector2(0.0, 0.5), Vector2(0.8, 0.5), + Vector2(-0.4, 1.2), Vector2(0.4, 1.2), + ] + for spot in spots: + var xz: Vector2 = spot + Vector2(origin.x, origin.z) + var crate := _glb_piece(CRATE_GLB, "wood", xz, false) + var crate_top: float = crate["top"] + # a few records stacked on the crate; smashing the crate spills them + for i in range(3): + var jitter := Vector2(randf_range(-0.06, 0.06), randf_range(-0.06, 0.06)) + var rec := _glb_piece(RECORD_GLB, "vinyl", xz + jitter, false, crate_top + float(i) * 0.03) + (crate["piece"] as Smashable).supports.append(rec["piece"]) - for y in shelf_ys: - # frozen shelf slab — smash THIS (or any leg) to drop everything above it. - var shelf := _piece("wood", Vector3(1.34, 0.05, 0.62), origin + Vector3(0, y, 0), true) - # every leg holds up every shelf: knock ANY leg -> both shelves drop (arcade call). - for post in posts: - post.supports.append(shelf) +## Instance a GLB as the VISUAL of a Smashable, give it a box collider auto-sized to +## the mesh AABB, and drop it so its bottom rests at height `sit_on`. Returns +## { piece: Smashable, top: float } so a caller can stack the next thing on top. +func _glb_piece(path: String, kind: String, xz: Vector2, frozen: bool, sit_on := 0.0) -> Dictionary: + var s := Smashable.new() + s.kind = kind + s.start_frozen = frozen + var packed := load(path) as PackedScene + var vis: Node3D = packed.instantiate() + s.add_child(vis) + _world.add_child(s) # in-tree so transforms/AABBs resolve + var ab := _body_local_aabb(s, vis) + if ab.size == Vector3.ZERO: + ab = AABB(Vector3(-0.2, 0.0, -0.2), Vector3(0.4, 0.4, 0.4)) # fallback + var col := CollisionShape3D.new() + var box := BoxShape3D.new() + box.size = ab.size + col.shape = box + col.position = ab.get_center() + s.add_child(col) + s.global_position = Vector3(xz.x, sit_on - ab.position.y, xz.y) # AABB bottom lands on sit_on + s.smashed.connect(_on_smashed) + return {"piece": s, "top": sit_on + ab.size.y} - # two crates resting on the shelf; the shelf holds them up. - for cx in [-0.34, 0.34]: - var crate_pos: Vector3 = origin + Vector3(cx, y + 0.22, 0) - var crate := _piece("wood", Vector3(0.5, 0.34, 0.5), crate_pos, false) - shelf.supports.append(crate) # shelf gone -> crate released too - # jackets + a record sit loose in the crate — already dynamic, they fall on - # their own once the crate/shelf is gone. Do NOT add them to supports. - var idx := 0 - for jz in [-0.14, -0.05, 0.05, 0.14]: - _piece("cardboard", Vector3(0.34, 0.34, 0.03), - crate_pos + Vector3(0, 0.12, jz), false) - if idx == 1: - # a record tucked in, lying flat-ish; brittle -> cracks on hard landing - _piece("vinyl", Vector3(0.15, 0.02, 0.15), - crate_pos + Vector3(0, 0.24, jz + 0.02), false, true) - idx += 1 +## Combined AABB of every MeshInstance3D under `visual_root`, in `body`'s local space +## (independent of where `body` currently sits in the world). +func _body_local_aabb(body: Node3D, visual_root: Node3D) -> AABB: + var mis: Array[MeshInstance3D] = [] + _collect_meshes(visual_root, mis) + var inv := body.global_transform.affine_inverse() + var acc := AABB() + var started := false + for mi in mis: + var a := mi.get_aabb() + var rel := inv * mi.global_transform + for i in range(8): + var corner := a.position + Vector3( + a.size.x * float(i & 1), + a.size.y * float((i >> 1) & 1), + a.size.z * float((i >> 2) & 1)) + var p := rel * corner + if not started: + acc = AABB(p, Vector3.ZERO) + started = true + else: + acc = acc.expand(p) + return acc + +func _collect_meshes(n: Node, acc: Array[MeshInstance3D]) -> void: + if n is MeshInstance3D: + acc.append(n) + for c in n.get_children(): + _collect_meshes(c, acc) func _piece(kind: String, size: Vector3, pos: Vector3, frozen: bool, cylinder := false) -> Smashable: var s := Smashable.new()