multyplayer
This commit is contained in:
@@ -1,12 +1,109 @@
|
||||
extends Node3D
|
||||
|
||||
var xr_interface :XRInterface
|
||||
## World manager. Owns the multiplayer spawners and the world-space main menu,
|
||||
## and turns NetworkManager's session events into spawned/despawned players and
|
||||
## seeded items.
|
||||
##
|
||||
## Startup:
|
||||
## - Command-line session (--server/--join): skip the menu, behave headlessly.
|
||||
## - Otherwise: embody a local player (so they can point) and show the menu; the
|
||||
## Host/Join/Solo buttons start the actual session.
|
||||
|
||||
func _ready():
|
||||
xr_interface = XRServer.find_interface("OpenXR")
|
||||
if xr_interface and xr_interface.is_initialized():
|
||||
print("OpenXR started :)")
|
||||
DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_DISABLED)
|
||||
get_viewport().use_xr = true
|
||||
const PLAYER_SCENE := preload("res://Player/Player.tscn")
|
||||
const CUBE_SCENE := "res://Items/PickupCube.tscn"
|
||||
|
||||
@onready var _players_spawner: MultiplayerSpawner = $PlayersSpawner
|
||||
@onready var _items_spawner: MultiplayerSpawner = $ItemsSpawner
|
||||
@onready var _menu: Node3D = $NetworkMenu
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
NetworkManager.register_world(self, _players_spawner, _items_spawner)
|
||||
NetworkManager.player_joined.connect(_on_player_joined)
|
||||
NetworkManager.player_left.connect(_on_player_left)
|
||||
NetworkManager.session_started.connect(_on_session_started)
|
||||
NetworkManager.connection_failed.connect(_on_connection_failed)
|
||||
_menu.host_pressed.connect(_on_menu_host)
|
||||
_menu.join_pressed.connect(_on_menu_join)
|
||||
_menu.solo_pressed.connect(_on_menu_solo)
|
||||
|
||||
# Start any command-line driven session now that we are listening.
|
||||
NetworkManager.world_ready()
|
||||
|
||||
if NetworkManager.is_online():
|
||||
# Command-line session: no menu.
|
||||
_menu.hide_menu()
|
||||
if _owns_spawning():
|
||||
_spawn_starting_items()
|
||||
else:
|
||||
print("OpenXR failed to start. Check your headset...")
|
||||
# Show the menu; embody a local player so they can point at it.
|
||||
_spawn_player(1)
|
||||
_menu.show_menu()
|
||||
|
||||
|
||||
# --- Menu button handlers --------------------------------------------------
|
||||
|
||||
func _on_menu_host() -> void:
|
||||
_menu.hide_menu()
|
||||
NetworkManager.host() # keeps the already-spawned local player (id 1)
|
||||
_spawn_starting_items()
|
||||
|
||||
|
||||
func _on_menu_solo() -> void:
|
||||
_menu.hide_menu()
|
||||
_spawn_starting_items()
|
||||
|
||||
|
||||
func _on_menu_join(ip: String) -> void:
|
||||
_menu.set_status("Connecting to %s ..." % ip)
|
||||
# Our placeholder id "1" belongs to the host once we join; drop it and let
|
||||
# the server spawn our real player.
|
||||
_despawn_player(1)
|
||||
NetworkManager.join(ip)
|
||||
|
||||
|
||||
func _on_session_started(is_server: bool) -> void:
|
||||
if not is_server:
|
||||
# Connected to a host as a client.
|
||||
_menu.hide_menu()
|
||||
|
||||
|
||||
func _on_connection_failed() -> void:
|
||||
_menu.set_status("Connection failed — check the IP")
|
||||
_spawn_player(1) # restore embodiment
|
||||
_menu.show_menu()
|
||||
|
||||
|
||||
# --- Player / item spawning ------------------------------------------------
|
||||
|
||||
func _on_player_joined(peer_id: int) -> void:
|
||||
if NetworkManager.is_server():
|
||||
_spawn_player(peer_id)
|
||||
|
||||
|
||||
func _on_player_left(peer_id: int) -> void:
|
||||
if NetworkManager.is_server():
|
||||
_despawn_player(peer_id)
|
||||
|
||||
|
||||
func _spawn_player(peer_id: int) -> void:
|
||||
if has_node(str(peer_id)):
|
||||
return
|
||||
var p := PLAYER_SCENE.instantiate()
|
||||
p.name = str(peer_id)
|
||||
add_child(p)
|
||||
|
||||
|
||||
func _despawn_player(peer_id: int) -> void:
|
||||
var n := get_node_or_null(str(peer_id))
|
||||
if n:
|
||||
n.queue_free()
|
||||
|
||||
|
||||
func _owns_spawning() -> bool:
|
||||
return not NetworkManager.is_online() or NetworkManager.is_server()
|
||||
|
||||
|
||||
func _spawn_starting_items() -> void:
|
||||
NetworkManager.spawn_item(CUBE_SCENE, Transform3D(Basis(), Vector3(-0.705, 1.576, -1.032)))
|
||||
NetworkManager.spawn_item(CUBE_SCENE, Transform3D(Basis(), Vector3(0.283, 1.561, -1.066)))
|
||||
|
||||
Reference in New Issue
Block a user