mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-14 18:02:38 +00:00
fix(arena): contain goal pockets
This commit is contained in:
@@ -14,6 +14,14 @@ signal goal_scored(team: int)
|
|||||||
# wall is thick or it pokes out the back of the arena. ArenaBoundary cuts the
|
# wall is thick or it pokes out the back of the arena. ArenaBoundary cuts the
|
||||||
# matching aperture in the hull (see its GOAL_APERTURE_* constants).
|
# matching aperture in the hull (see its GOAL_APERTURE_* constants).
|
||||||
const POCKET_DEPTH := ArenaBoundary.SURFACE_THICKNESS
|
const POCKET_DEPTH := ArenaBoundary.SURFACE_THICKNESS
|
||||||
|
# Physical back wall for the goal pocket. The arena end wall has a real hole
|
||||||
|
# at the scoring aperture; without this, the visual-only net lets ships and
|
||||||
|
# the ball leave the enclosure after crossing the sensor. A small overlap
|
||||||
|
# into the surrounding end-wall panels closes numerical seams at the rim.
|
||||||
|
const BACKSTOP_THICKNESS := 0.4
|
||||||
|
const BACKSTOP_EDGE_OVERLAP := 0.25
|
||||||
|
const ARENA_COLLISION_LAYER := 1 << 2
|
||||||
|
const ARENA_COLLISION_MASK := (1 << 0) | (1 << 1)
|
||||||
# Clearance between the mouth and the pocket shell, so the pocket's side walls
|
# Clearance between the mouth and the pocket shell, so the pocket's side walls
|
||||||
# stay hidden behind the hull rather than showing at the aperture edge.
|
# stay hidden behind the hull rather than showing at the aperture edge.
|
||||||
const POCKET_CLEARANCE := 0.2
|
const POCKET_CLEARANCE := 0.2
|
||||||
@@ -32,6 +40,7 @@ var _goal_burst: GPUParticles3D
|
|||||||
func _ready():
|
func _ready():
|
||||||
# Group lets AI controllers and game modes discover goals
|
# Group lets AI controllers and game modes discover goals
|
||||||
add_to_group("goal")
|
add_to_group("goal")
|
||||||
|
_build_backstop()
|
||||||
# Everything below _on_body_entered is decoration, and training spawns
|
# Everything below _on_body_entered is decoration, and training spawns
|
||||||
# headless arenas that never render it. The sensor is unaffected.
|
# headless arenas that never render it. The sensor is unaffected.
|
||||||
if DisplayServer.get_name() != "headless":
|
if DisplayServer.get_name() != "headless":
|
||||||
@@ -46,6 +55,26 @@ func _on_body_entered(body):
|
|||||||
goal_scored.emit(team)
|
goal_scored.emit(team)
|
||||||
|
|
||||||
|
|
||||||
|
func _build_backstop() -> void:
|
||||||
|
var mouth := ($CollisionShape3D.shape as BoxShape3D).size
|
||||||
|
var body := StaticBody3D.new()
|
||||||
|
body.name = "PocketBackstop"
|
||||||
|
body.collision_layer = ARENA_COLLISION_LAYER
|
||||||
|
body.collision_mask = ARENA_COLLISION_MASK
|
||||||
|
var collision := CollisionShape3D.new()
|
||||||
|
collision.name = "CollisionShape3D"
|
||||||
|
var box := BoxShape3D.new()
|
||||||
|
box.size = Vector3(
|
||||||
|
mouth.x + BACKSTOP_EDGE_OVERLAP * 2.0,
|
||||||
|
mouth.y + BACKSTOP_EDGE_OVERLAP * 2.0,
|
||||||
|
BACKSTOP_THICKNESS
|
||||||
|
)
|
||||||
|
collision.shape = box
|
||||||
|
collision.position = Vector3(0.0, 0.0, POCKET_DEPTH)
|
||||||
|
body.add_child(collision)
|
||||||
|
add_child(body)
|
||||||
|
|
||||||
|
|
||||||
# --- visuals -----------------------------------------------------------------
|
# --- visuals -----------------------------------------------------------------
|
||||||
# Cosmetic only. The mouth is measured off the sensor's own collision shape, so
|
# Cosmetic only. The mouth is measured off the sensor's own collision shape, so
|
||||||
# the frame can never drift from the volume that actually scores.
|
# the frame can never drift from the volume that actually scores.
|
||||||
|
|||||||
Reference in New Issue
Block a user