Add VRSpectatorCamera so the server viewport follows VR head

This commit is contained in:
JonShard
2026-08-17 11:04:49 +02:00
parent 4a8d5b879e
commit 0bb00735b2
4 changed files with 56 additions and 3 deletions
+9 -3
View File
@@ -6,9 +6,9 @@
[ext_resource type="Sky" uid="uid://c1abtpwhdm2d5" path="res://textures/sky/NightSkyHDRI009_16K.tres" id="5_c3xgf"] [ext_resource type="Sky" uid="uid://c1abtpwhdm2d5" path="res://textures/sky/NightSkyHDRI009_16K.tres" id="5_c3xgf"]
[ext_resource type="Script" uid="uid://fyd2rjramhbb" path="res://prefabs/kitchen_instantiator.gd" id="6_pw2j5"] [ext_resource type="Script" uid="uid://fyd2rjramhbb" path="res://prefabs/kitchen_instantiator.gd" id="6_pw2j5"]
[ext_resource type="PackedScene" uid="uid://damrxtlt7uswf" path="res://content/station_layouts/small_line.tscn" id="7_0sjqq"] [ext_resource type="PackedScene" uid="uid://damrxtlt7uswf" path="res://content/station_layouts/small_line.tscn" id="7_0sjqq"]
[ext_resource type="PackedScene" uid="uid://j7caslh27nor" path="res://stations/Hob_old.tscn" id="8_0sjqq"]
[ext_resource type="PackedScene" uid="uid://dm70ynyuw1a5u" path="res://prefabs/day_controller.tscn" id="9_5wx0o"] [ext_resource type="PackedScene" uid="uid://dm70ynyuw1a5u" path="res://prefabs/day_controller.tscn" id="9_5wx0o"]
[ext_resource type="PackedScene" uid="uid://bnwb7imcotkod" path="res://prefabs/build_mode_controller.tscn" id="10_464r1"] [ext_resource type="PackedScene" uid="uid://bnwb7imcotkod" path="res://prefabs/build_mode_controller.tscn" id="10_464r1"]
[ext_resource type="Script" uid="uid://c4y0yigqv7355" path="res://test/vr_spectator_camera.gd" id="11_5wx0o"]
[ext_resource type="PackedScene" uid="uid://dxe05wp60jg3l" path="res://scenes/queue_controller.tscn" id="11_de1dy"] [ext_resource type="PackedScene" uid="uid://dxe05wp60jg3l" path="res://scenes/queue_controller.tscn" id="11_de1dy"]
[ext_resource type="Script" uid="uid://biu4qr3nr1eny" path="res://test/mp_test_driver.gd" id="99_mptst"] [ext_resource type="Script" uid="uid://biu4qr3nr1eny" path="res://test/mp_test_driver.gd" id="99_mptst"]
@@ -31,6 +31,9 @@ sdfgi_enabled = true
[sub_resource type="BoxShape3D" id="BoxShape3D_arao0"] [sub_resource type="BoxShape3D" id="BoxShape3D_arao0"]
size = Vector3(15, 20, 0.1) size = Vector3(15, 20, 0.1)
[sub_resource type="Resource" id="Resource_464r1"]
metadata/__load_path__ = "res://stations/Hob_old.tscn"
[node name="Main" type="Node3D" unique_id=1312265607 node_paths=PackedStringArray("items_spawner", "players_spawner")] [node name="Main" type="Node3D" unique_id=1312265607 node_paths=PackedStringArray("items_spawner", "players_spawner")]
script = ExtResource("1_kdan8") script = ExtResource("1_kdan8")
items_spawner = NodePath("ItemsSpawner") items_spawner = NodePath("ItemsSpawner")
@@ -63,7 +66,7 @@ environment = SubResource("Environment_bvwq1")
spawn_path = NodePath("../WorldContent") spawn_path = NodePath("../WorldContent")
[node name="PlayersSpawner" type="MultiplayerSpawner" parent="." unique_id=106645565] [node name="PlayersSpawner" type="MultiplayerSpawner" parent="." unique_id=106645565]
_spawnable_scenes = PackedStringArray("res://Player/net_player.tscn") _spawnable_scenes = PackedStringArray("uid://c58ns7csdahjy")
spawn_path = NodePath("../Players") spawn_path = NodePath("../Players")
[node name="StaticBody3D" type="StaticBody3D" parent="." unique_id=4404969] [node name="StaticBody3D" type="StaticBody3D" parent="." unique_id=4404969]
@@ -91,7 +94,7 @@ script = ExtResource("99_mptst")
transform = Transform3D(1, 0, -1.7484555e-07, 0, 1, 0, 1.7484555e-07, 0, 1, 0, 0, -1.2) transform = Transform3D(1, 0, -1.7484555e-07, 0, 1, 0, 1.7484555e-07, 0, 1, 0, 0, -1.2)
script = ExtResource("6_pw2j5") script = ExtResource("6_pw2j5")
kitchen_scene = ExtResource("7_0sjqq") kitchen_scene = ExtResource("7_0sjqq")
hob_scene = ExtResource("8_0sjqq") hob_scene = SubResource("Resource_464r1")
[node name="DayController" parent="." unique_id=1418639156 instance=ExtResource("9_5wx0o")] [node name="DayController" parent="." unique_id=1418639156 instance=ExtResource("9_5wx0o")]
@@ -99,3 +102,6 @@ hob_scene = ExtResource("8_0sjqq")
[node name="QueueController" parent="." unique_id=326512876 instance=ExtResource("11_de1dy")] [node name="QueueController" parent="." unique_id=326512876 instance=ExtResource("11_de1dy")]
transform = Transform3D(-1, 0, -8.742278e-08, 0, 1, 0, 8.742278e-08, 0, -1, 0, 0, 7.2000003) transform = Transform3D(-1, 0, -8.742278e-08, 0, 1, 0, 8.742278e-08, 0, -1, 0, 0, 7.2000003)
[node name="Node3D" type="Node3D" parent="." unique_id=1675081068]
script = ExtResource("11_5wx0o")
+40
View File
@@ -0,0 +1,40 @@
class_name VrSpectatorCamera
extends Node
# Debug tool: on a non-VR client, follows a connected VR client's head so you can spectate it.
@export var players_path: NodePath = ^"../Players"
@onready var _players: Node = get_node_or_null(players_path)
var _camera: Camera3D
func _ready() -> void:
var xr_interface := XRServer.find_interface("OpenXR")
if xr_interface and xr_interface.is_initialized():
SweetLogger.warning("{0} disabled - this instance is the VR client", [name])
return
if not _players:
SweetLogger.warning("{0} could not resolve players_path {1}", [name, players_path])
return
_camera = Camera3D.new()
add_child(_camera)
_camera.make_current()
func _process(_delta: float) -> void:
if not _camera:
return
var head := _find_remote_head()
if head:
_camera.global_transform = head.global_transform
# First connected player that isn't this local peer
func _find_remote_head() -> Node3D:
var my_id := multiplayer.get_unique_id()
for player in _players.get_children():
if player.name == str(my_id):
continue
return player.get_node_or_null("Head")
return null
+1
View File
@@ -0,0 +1 @@
uid://c4y0yigqv7355
+6
View File
@@ -0,0 +1,6 @@
[gd_scene format=3 uid="uid://3i1xb74cfsh5"]
[ext_resource type="Script" uid="uid://c4y0yigqv7355" path="res://test/vr_spectator_camera.gd" id="1_6xorv"]
[node name="VRSpectatorCamera" type="Node" unique_id=310823561]
script = ExtResource("1_6xorv")