48 lines
1.6 KiB
GDScript
48 lines
1.6 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 focus: Node3D # the boat
|
|
@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
|
|
|
|
|
|
func true_position(node: Node3D) -> Vector3:
|
|
return node.global_position + origin_offset
|
|
|
|
|
|
func _physics_process(_delta: float) -> void:
|
|
_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
|
|
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
|