feat(*): add wall/ceiling surface pull and retune ball-ship materials

This commit is contained in:
Josh Creek
2026-07-20 19:33:28 +01:00
parent e23d780402
commit 46c8275523
7 changed files with 95 additions and 4 deletions
+32
View File
@@ -60,10 +60,42 @@ var _corner_visuals: Array[Dictionary] = []
func _ready() -> void:
add_to_group("arena_boundary")
_build_corner_curves()
_build_base_fillets()
# Wall+ceiling-only proximity force field ("artificial gravity" grav-plating,
# weaker than the floor's plain default gravity, which this deliberately
# leaves untouched). Ship and Ball each call this with their own
# strength/range so wall adherence and ceiling adherence can be tuned
# independently per body — see ship.gd/ball.gd. Quadratic falloff keeps a
# casual flyby near a wall almost force-free, concentrating the pull in
# roughly the last third of the range so it only bites once something is
# genuinely close to the surface.
func get_surface_pull(
global_pos: Vector3, wall_strength: float, wall_range: float,
ceiling_strength: float, ceiling_range: float
) -> Vector3:
var p := to_local(global_pos)
var pull := Vector3.ZERO
pull += Vector3(1, 0, 0) * _falloff(INNER_HALF_X - p.x, wall_range) * wall_strength
pull += Vector3(-1, 0, 0) * _falloff(INNER_HALF_X + p.x, wall_range) * wall_strength
# End walls are gated off inside the goal mouth — there is no physical
# wall there (see GOAL_MOUTH_HALF_WIDTH / _build_base_fillets), so a shot
# heading straight for the net doesn't feel a phantom sideways tug.
if abs(p.x) >= GOAL_MOUTH_HALF_WIDTH:
pull += Vector3(0, 0, 1) * _falloff(INNER_HALF_Z - p.z, wall_range) * wall_strength
pull += Vector3(0, 0, -1) * _falloff(INNER_HALF_Z + p.z, wall_range) * wall_strength
pull += Vector3.UP * _falloff(INNER_HEIGHT - p.y, ceiling_range) * ceiling_strength
return pull
func _falloff(dist: float, field_range: float) -> float:
var t: float = clamp(1.0 - dist / field_range, 0.0, 1.0)
return t * t
func _process(_delta: float) -> void:
# The translucent field material tints everything behind it, so any face
# the camera has crossed to the outside of is hidden entirely — looking