This commit is contained in:
algodoogle
2026-07-25 19:26:43 +01:00
parent f7024db98d
commit 596d777fae
32 changed files with 832 additions and 257 deletions
+50
View File
@@ -0,0 +1,50 @@
extends Node3D
## Networked representation of one connected player. The owning peer's local
## XR rig (found via the "local_xr_origin" group) drives Head/LeftHand/
## RightHand each frame; the MultiplayerSynchronizer replicates those
## transforms so every other peer sees a matching avatar.
@onready var _head: Node3D = $Head
@onready var _left_hand: Node3D = $LeftHand
@onready var _right_hand: Node3D = $RightHand
var _local_camera: Node3D
var _local_left_hand: Node3D
var _local_right_hand: Node3D
func _enter_tree() -> void:
# MultiplayerSynchronizer resolves authority when this node enters the
# tree, so authority must be set here rather than in _ready(), or the
# first synced frames go the wrong direction.
set_multiplayer_authority(str(name).to_int())
func _ready() -> void:
if is_multiplayer_authority():
var origin := get_tree().get_first_node_in_group("local_xr_origin")
if origin:
_local_camera = origin.get_node_or_null("XRCamera3D")
_local_left_hand = origin.get_node_or_null("XRControllerLeftHand")
_local_right_hand = origin.get_node_or_null("XRControllerRightHand")
# Every peer's rig is baked at the same spot in the scene; spread
# joiners out along X by peer id so they don't start stacked on
# top of each other (host/peer 1 keeps the original spot).
var peer_id := str(name).to_int()
origin.position += Vector3((peer_id - 1) * 1.5, 0, 0)
# Don't render your own floating head/hands from the inside.
_head.visible = false
_left_hand.visible = false
_right_hand.visible = false
else:
set_process(false)
func _process(_delta: float) -> void:
if _local_camera:
_head.global_transform = _local_camera.global_transform
if _local_left_hand:
_left_hand.global_transform = _local_left_hand.global_transform
if _local_right_hand:
_right_hand.global_transform = _local_right_hand.global_transform
+1
View File
@@ -0,0 +1 @@
uid://bncuxh7j7ix5q
+44
View File
@@ -0,0 +1,44 @@
[gd_scene load_steps=5 format=3]
[ext_resource type="Script" path="res://Player/net_player.gd" id="1_np001"]
[ext_resource type="PackedScene" uid="uid://bq86r4yll8po" path="res://addons/godot-xr-tools/hands/scenes/lowpoly/left_fullglove_low.tscn" id="2_np002"]
[ext_resource type="PackedScene" uid="uid://xqimcf20s2jp" path="res://addons/godot-xr-tools/hands/scenes/lowpoly/right_fullglove_low.tscn" id="3_np003"]
[sub_resource type="CapsuleMesh" id="CapsuleMesh_np004"]
radius = 0.09
height = 0.22
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_np005"]
properties/0/path = NodePath("Head:position")
properties/0/spawn = false
properties/0/replication_mode = 1
properties/1/path = NodePath("Head:quaternion")
properties/1/spawn = false
properties/1/replication_mode = 1
properties/2/path = NodePath("LeftHand:position")
properties/2/spawn = false
properties/2/replication_mode = 1
properties/3/path = NodePath("LeftHand:quaternion")
properties/3/spawn = false
properties/3/replication_mode = 1
properties/4/path = NodePath("RightHand:position")
properties/4/spawn = false
properties/4/replication_mode = 1
properties/5/path = NodePath("RightHand:quaternion")
properties/5/spawn = false
properties/5/replication_mode = 1
[node name="NetPlayer" type="Node3D"]
script = ExtResource("1_np001")
[node name="Head" type="MeshInstance3D" parent="."]
mesh = SubResource("CapsuleMesh_np004")
[node name="LeftHand" parent="." instance=ExtResource("2_np002")]
[node name="RightHand" parent="." instance=ExtResource("3_np003")]
[node name="Sync" type="MultiplayerSynchronizer" parent="."]
root_path = NodePath("..")
replication_config = SubResource("SceneReplicationConfig_np005")
replication_interval = 0.033