Godot Version
4.4.1.stable
Question
How can I synchronize the position of each boulder across all players in a multiplayer environment, while allowing each player to summon and propel boulders that persist in the world and remain synced in real-time?
extends Node
# Resources
var boulder = preload("res://scenes/human/moulder class/boulder.tscn")
@onready var ray := $"../Head/Camera3D/interactRay"
@onready var cam := $"../Head/Camera3D"
@onready var hand := $"../Head/Camera3D/hand"
@onready var line := MeshInstance3D.new()
@export var pull := {
"max_distance": 3.0,
"max_force": 10.0,
"min_size": 0.3,
"max_size": 1.0
}
@export var hit := {
"force": 15.0,
"cooldown": 0.5
}
@export var shake := {
"intensity": 0.2,
"decay": 5.0,
"max_offset": Vector3(0.3, 0.3, 0.0)
}
var pulling := false
var origin := Vector3.ZERO
var strength := 0.0
var trauma := 0.0
var can_hit := true
var noise := FastNoiseLite.new()
func _ready():
noise.seed = randi()
func _physics_process(delta):
handle_pull(delta)
handle_hit()
update_shake(delta)
func handle_pull(delta):
if ray.is_colliding() and not pulling and Input.is_action_just_pressed("l_click"):
start_pull(ray.get_collision_point())
if pulling:
strength = update_strength()
if Input.is_action_just_released("l_click"):
launch_boulder()
func handle_hit():
if Input.is_action_just_pressed("r_click") and can_hit and ray.is_colliding():
var body = ray.get_collider()
if body.is_in_group("earth_body"):
hit_body(body)
can_hit = false
await get_tree().create_timer(hit.cooldown).timeout
can_hit = true
func start_pull(pos: Vector3):
pulling = true
origin = pos
func update_strength() -> float:
var dist = hand.global_position.distance_to(origin)
return clamp(dist / pull.max_distance, 0.0, 1.0)
func launch_boulder():
var dir = (hand.global_position - origin).normalized()
var force = strength * pull.max_force
var size = lerp(pull.min_size, pull.max_size, strength)
var b = boulder.instantiate()
b.position = origin
b.scale = Vector3.ONE * size
get_tree().current_scene.add_child(b)
await get_tree().physics_frame
b.apply_central_impulse(dir * force)
add_trauma(strength * shake.intensity * 2)
pulling = false
line.mesh = null
func hit_body(body: RigidBody3D):
var dir = (body.global_position - cam.global_position).normalized()
body.apply_central_impulse(dir * hit.force)
add_trauma(0.4)
func add_trauma(amount: float):
trauma = min(trauma + amount, 1.0)
func update_shake(delta):
if trauma > 0:
trauma = max(0, trauma - shake.decay * delta)
var intensity = trauma * trauma
cam.position = Vector3(
shake.max_offset.x * intensity * noise.get_noise_1d(Time.get_ticks_msec() * 0.01),
shake.max_offset.y * intensity * noise.get_noise_1d(Time.get_ticks_msec() * 0.01 + 100),
0
)
elif cam.position != Vector3.ZERO:
cam.position = cam.position.lerp(Vector3.ZERO, min(10 * delta, 1.0))