Files
VRyHungry1/Player/player.gd
T
algodoogle 1869dbf054 multyplayer
2026-07-16 18:36:49 +01:00

81 lines
2.5 KiB
GDScript

extends Node3D
## One instance per connected peer. The owning peer is the multiplayer
## authority. The local (authority) player builds the full XR rig from
## XROrigin.tscn and feeds its head/hand poses into synced properties; remote
## players show a lightweight avatar driven by those synced poses.
const RIG_SCENE := preload("res://XROrigin.tscn")
# Synced avatar pose. Authority writes these from the XR trackers each frame;
# remotes read them onto the Avatar. net_heartbeat is a monotonic counter used
# to confirm replication is live (also handy for debugging).
@export var head_xform: Transform3D = Transform3D.IDENTITY
@export var left_xform: Transform3D = Transform3D.IDENTITY
@export var right_xform: Transform3D = Transform3D.IDENTITY
@export var net_heartbeat: int = 0
var _rig: Node3D
var _camera: Node3D
var _left: Node3D
var _right: Node3D
var _is_local := false
@onready var _avatar: Node3D = $Avatar
@onready var _avatar_head: Node3D = $Avatar/Head
@onready var _avatar_left: Node3D = $Avatar/LeftHand
@onready var _avatar_right: Node3D = $Avatar/RightHand
func _enter_tree() -> void:
# The spawner names each player by its owning peer id.
set_multiplayer_authority(str(name).to_int())
# (replication config is authored in Player.tscn's MultiplayerSynchronizer)
func _ready() -> void:
_is_local = is_multiplayer_authority()
if _is_local:
_setup_local()
else:
_setup_remote()
if Engine.has_singleton("NetworkManager") or get_node_or_null("/root/NetworkManager"):
NetworkManager.log_line("Player %s ready (authority=%d local=%s)" % [name, get_multiplayer_authority(), str(_is_local)])
func _setup_local() -> void:
# We see through the headset; hide our own avatar mesh.
_avatar.visible = false
_rig = RIG_SCENE.instantiate()
add_child(_rig)
_camera = _rig.get_node_or_null("XRCamera3D")
_left = _rig.get_node_or_null("XRControllerLeftHand")
_right = _rig.get_node_or_null("XRControllerRightHand")
_enable_xr()
func _enable_xr() -> void:
var xr := XRServer.find_interface("OpenXR")
if xr and xr.is_initialized():
get_viewport().use_xr = true
DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_DISABLED)
func _setup_remote() -> void:
_avatar.visible = true
func _process(_delta: float) -> void:
if _is_local:
if _camera:
head_xform = _camera.global_transform
left_xform = _left.global_transform
right_xform = _right.global_transform
net_heartbeat += 1
else:
_avatar_head.global_transform = head_xform
_avatar_left.global_transform = left_xform
_avatar_right.global_transform = right_xform