Files
2026-07-07 11:53:39 +02:00

53 lines
1.7 KiB
GDScript

class_name WorldManager
extends Node
## Owns "where is the player and what stays centered on them":
## recenters scenery in the follow_focus group, and shifts the origin
## (teleporting the shift_with_origin group) before float precision degrades.
@export var ocean: Ocean
## Distance from origin that triggers an origin shift.
@export var shift_threshold := 2048.0
## Default recenter step; nodes can override with a follow_step metadata.
## Keep it a multiple of the ocean's vertex_spacing.
@export var follow_step := 16.0
## True world position of the current local origin (grows over a long voyage).
var origin_offset := Vector3.ZERO
var focus: Node3D # Controlled by PlayerController
func true_position(node: Node3D) -> Vector3:
return node.global_position + origin_offset
func _physics_process(_delta: float) -> void:
if focus == null:
return
_maybe_shift_origin()
_recenter_followers()
func _maybe_shift_origin() -> void:
var p := focus.global_position
if Vector2(p.x, p.z).length() < shift_threshold:
return
var shift := Vector3(snappedf(p.x, follow_step), 0.0, snappedf(p.z, follow_step))
origin_offset += shift
for node in get_tree().get_nodes_in_group("shift_with_origin"):
node.global_position -= shift
node.reset_physics_interpolation()
ocean.shift_origin(shift)
func _recenter_followers() -> void:
for node in get_tree().get_nodes_in_group("follow_focus"):
var step: float = node.get_meta("follow_step", follow_step)
var new_x := snappedf(focus.global_position.x, step)
var new_z := snappedf(focus.global_position.z, step)
if new_x != node.global_position.x or new_z != node.global_position.z:
node.global_position.x = new_x
node.global_position.z = new_z
node.reset_physics_interpolation()