Godot Version
Godot Version 4.2.1 stable
Question
I am attempting to make a 3D multiplayer game that requires players to choose aspects of their character in a lobby.
Right now I have a system where the game successfully allows two players (the limit for now) to join a lobby, but both character’s movement and position is controlled by the host. Additionally, both screens show the host’s character’s camera.
Here are screenshots of the relevant scenes:
Here are relevant scripts:
scene_manage.gd (attached to Spawns):
@export var player_scene: PackedScene
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
var index = 0
for i in global_ids.players:
var current_player = player_scene.instantiate()
add_child(current_player)
for spawn in get_tree().get_nodes_in_group("spawn"):
if spawn.name == str(index):
current_player.global_position = spawn.global_position
index += 1
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
pass
multi_manage.gd (attached to MainMenu):
extends Control
@export var address = "127.0.0.1"
@export var port = 9972
var peer
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
multiplayer.peer_connected.connect(peer_connected)
multiplayer.peer_disconnected.connect(peer_disconnected)
multiplayer.connected_to_server.connect(connected_to_server)
multiplayer.connection_failed.connect(connection_failed)
pass # Replace with function body.
func peer_connected(peer_id):
print("Player " + str(peer_id) + " connected!")
func peer_disconnected(peer_id):
print("Player " + str(peer_id) + " disconnected.")
func connected_to_server():
print("Successfully connected!")
send_peer_info.rpc_id(1, $CanvasLayer/PanelContainer/MarginContainer/VBoxContainer/Enter_Name.text, multiplayer.get_unique_id())
func connection_failed():
print("Failed to connect.")
@rpc("any_peer")
func send_peer_info(name, peer_id):
if !global_ids.players.has(peer_id):
global_ids.players[peer_id] ={
"name" : name,
"peer_id" : peer_id,
}
if multiplayer.is_server():
for i in global_ids.players:
send_peer_info.rpc(global_ids.players[i].name, i)
@rpc("any_peer", "call_local")
func start_game():
var scene = load("res://Scenes/world.tscn").instantiate()
get_tree().root.add_child(scene)
self.hide()
$CanvasLayer.hide()
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
pass
func _on_host_pressed() -> void:
peer = ENetMultiplayerPeer.new()
var error = peer.create_server(port, 6)
if error != OK:
print("Hosting failed: " + error)
return
peer.get_host().compress(ENetConnection.COMPRESS_RANGE_CODER)
multiplayer.set_multiplayer_peer(peer)
print("Waiting for players...")
send_peer_info($CanvasLayer/PanelContainer/MarginContainer/VBoxContainer/Enter_Name.text, multiplayer.get_unique_id())
func _on_join_pressed() -> void:
peer = ENetMultiplayerPeer.new()
peer.create_client(address, port)
peer.get_host().compress(ENetConnection.COMPRESS_RANGE_CODER)
multiplayer.set_multiplayer_peer(peer)
func _on_start_pressed() -> void:
start_game.rpc()
global_ids.gd (script to store global variables):
extends Node
var players = {}
The player script is a standard controller with no multiplayer code.
The world script handles some non-multiplayer stuff and isn’t relevant.
Lmk if you need more information


