add multiplayer lobby system
This commit is contained in:
parent
3eb8b2a718
commit
ef8553fe45
|
@ -0,0 +1,15 @@
|
||||||
|
extends MultiplayerSpawner
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
set_multiplayer_authority(1)
|
||||||
|
spawn_function = spawn_player
|
||||||
|
|
||||||
|
func spawn_player(owner_id: int):
|
||||||
|
var player := preload("res://player/player.tscn").instantiate()
|
||||||
|
player.set_multiplayer_authority(owner_id)
|
||||||
|
if multiplayer.get_unique_id() == owner_id:
|
||||||
|
var camera := preload("res://camera/camera.tscn").instantiate()
|
||||||
|
player.add_child(camera)
|
||||||
|
player.position.y = 5.0
|
||||||
|
return player
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
extends Node3D
|
||||||
|
|
||||||
|
# Called from the server
|
||||||
|
func server_add_player(id: int):
|
||||||
|
%PlayerSpawner.spawn(id)
|
|
@ -1,10 +1,10 @@
|
||||||
[gd_scene load_steps=8 format=3 uid="uid://b00brfkibo5cj"]
|
[gd_scene load_steps=8 format=3 uid="uid://b00brfkibo5cj"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://bq654gwim6col" path="res://level/level.glb" id="1_s37in"]
|
[ext_resource type="PackedScene" uid="uid://bq654gwim6col" path="res://level/level.glb" id="1_s37in"]
|
||||||
[ext_resource type="PackedScene" uid="uid://do25xvpy80iio" path="res://player/player.tscn" id="2_7ct70"]
|
|
||||||
[ext_resource type="Environment" uid="uid://covjrwmk4rplw" path="res://level/world_environment.tres" id="2_ptkl6"]
|
[ext_resource type="Environment" uid="uid://covjrwmk4rplw" path="res://level/world_environment.tres" id="2_ptkl6"]
|
||||||
[ext_resource type="PackedScene" uid="uid://brgqf2ebuyhuy" path="res://camera/camera.tscn" id="3_yev7j"]
|
[ext_resource type="Script" path="res://level/level.gd" id="2_s1bx6"]
|
||||||
[ext_resource type="Script" path="res://addons/smoother/smoother.gd" id="5_2tyle"]
|
[ext_resource type="Script" path="res://addons/smoother/smoother.gd" id="5_2tyle"]
|
||||||
|
[ext_resource type="Script" path="res://level/PlayerSpawner.gd" id="6_7ww0m"]
|
||||||
|
|
||||||
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_ujmev"]
|
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_ujmev"]
|
||||||
margin = 2.067
|
margin = 2.067
|
||||||
|
@ -13,6 +13,7 @@ margin = 2.067
|
||||||
size = Vector3(2, 0.1, 2)
|
size = Vector3(2, 0.1, 2)
|
||||||
|
|
||||||
[node name="level" instance=ExtResource("1_s37in")]
|
[node name="level" instance=ExtResource("1_s37in")]
|
||||||
|
script = ExtResource("2_s1bx6")
|
||||||
|
|
||||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="." index="0"]
|
[node name="WorldEnvironment" type="WorldEnvironment" parent="." index="0"]
|
||||||
environment = ExtResource("2_ptkl6")
|
environment = ExtResource("2_ptkl6")
|
||||||
|
@ -30,17 +31,14 @@ shape = SubResource("WorldBoundaryShape3D_ujmev")
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.05, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.05, 0)
|
||||||
shape = SubResource("BoxShape3D_qp06x")
|
shape = SubResource("BoxShape3D_qp06x")
|
||||||
|
|
||||||
[node name="Player" parent="." index="3" instance=ExtResource("2_7ct70")]
|
[node name="Players" type="Node3D" parent="." index="3"]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.36667, 2.66437, 0)
|
unique_name_in_owner = true
|
||||||
floor_max_angle = 1.309
|
|
||||||
JUMP_VELOCITY = 5.0
|
|
||||||
|
|
||||||
[node name="Camera" parent="Player" index="2" instance=ExtResource("3_yev7j")]
|
[node name="PlayerSpawner" type="MultiplayerSpawner" parent="." index="4"]
|
||||||
|
unique_name_in_owner = true
|
||||||
[node name="Players" type="Node3D" parent="." index="4"]
|
_spawnable_scenes = PackedStringArray("res://player/player.tscn")
|
||||||
|
spawn_path = NodePath("../Players")
|
||||||
|
script = ExtResource("6_7ww0m")
|
||||||
|
|
||||||
[node name="Smoother" type="Node" parent="." index="5"]
|
[node name="Smoother" type="Node" parent="." index="5"]
|
||||||
script = ExtResource("5_2tyle")
|
script = ExtResource("5_2tyle")
|
||||||
|
|
||||||
[node name="MultiplayerSpawner" type="MultiplayerSpawner" parent="." index="6"]
|
|
||||||
spawn_path = NodePath("../Players")
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
extends Control
|
||||||
|
|
||||||
|
|
||||||
|
func _on_create_server_pressed():
|
||||||
|
get_tree().change_scene_to_file("res://server/server.tscn")
|
||||||
|
|
||||||
|
|
||||||
|
func _on_connect_to_server_pressed():
|
||||||
|
var address: String = %ConnectIP.text
|
||||||
|
var port := int(%ConnectPort.text)
|
||||||
|
var parent := get_parent()
|
||||||
|
queue_free()
|
||||||
|
var scene := preload("res://server/client_lobbies.tscn").instantiate()
|
||||||
|
scene.address = address
|
||||||
|
scene.port = port
|
||||||
|
parent.add_child(scene)
|
|
@ -0,0 +1,51 @@
|
||||||
|
[gd_scene load_steps=2 format=3 uid="uid://b4tgnq0dwf13"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://menu/main_menu.gd" id="1_q1k1j"]
|
||||||
|
|
||||||
|
[node name="MainMenu" type="Control"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = ExtResource("1_q1k1j")
|
||||||
|
|
||||||
|
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
|
||||||
|
[node name="CreateServer" type="Button" parent="VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Start Server"
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Server IP"
|
||||||
|
|
||||||
|
[node name="ConnectIP" type="TextEdit" parent="VBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 61.195)
|
||||||
|
layout_mode = 2
|
||||||
|
text = "127.0.0.1"
|
||||||
|
|
||||||
|
[node name="Label2" type="Label" parent="VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Server Port"
|
||||||
|
|
||||||
|
[node name="ConnectPort" type="TextEdit" parent="VBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 61.195)
|
||||||
|
layout_mode = 2
|
||||||
|
text = "3000"
|
||||||
|
|
||||||
|
[node name="ConnectToServer" type="Button" parent="VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Connect To Server"
|
||||||
|
|
||||||
|
[connection signal="pressed" from="VBoxContainer/CreateServer" to="." method="_on_create_server_pressed"]
|
||||||
|
[connection signal="pressed" from="VBoxContainer/ConnectToServer" to="." method="_on_connect_to_server_pressed"]
|
|
@ -7,15 +7,14 @@
|
||||||
properties/0/path = NodePath(".:position")
|
properties/0/path = NodePath(".:position")
|
||||||
properties/0/spawn = true
|
properties/0/spawn = true
|
||||||
properties/0/replication_mode = 1
|
properties/0/replication_mode = 1
|
||||||
properties/1/path = NodePath("player:velocity")
|
|
||||||
properties/1/spawn = true
|
|
||||||
properties/1/replication_mode = 1
|
|
||||||
|
|
||||||
[sub_resource type="SphereShape3D" id="SphereShape3D_t1htn"]
|
[sub_resource type="SphereShape3D" id="SphereShape3D_t1htn"]
|
||||||
radius = 0.986757
|
radius = 0.986757
|
||||||
|
|
||||||
[node name="player" instance=ExtResource("1_0u2un")]
|
[node name="player" instance=ExtResource("1_0u2un")]
|
||||||
|
floor_max_angle = 1.32121
|
||||||
script = ExtResource("1_gh340")
|
script = ExtResource("1_gh340")
|
||||||
|
JUMP_VELOCITY = 8.0
|
||||||
|
|
||||||
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="." index="0"]
|
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="." index="0"]
|
||||||
replication_config = SubResource("SceneReplicationConfig_u4bmc")
|
replication_config = SubResource("SceneReplicationConfig_u4bmc")
|
||||||
|
|
|
@ -29,9 +29,14 @@ DSP/dsp_buffer_count=4
|
||||||
[application]
|
[application]
|
||||||
|
|
||||||
config/name="Grounders"
|
config/name="Grounders"
|
||||||
|
run/main_scene="res://menu/main_menu.tscn"
|
||||||
config/features=PackedStringArray("4.2", "Forward Plus")
|
config/features=PackedStringArray("4.2", "Forward Plus")
|
||||||
config/icon="res://icon.svg"
|
config/icon="res://icon.svg"
|
||||||
|
|
||||||
|
[autoload]
|
||||||
|
|
||||||
|
MultiplayerEvents="*res://server/MultiplayerEvents.gd"
|
||||||
|
|
||||||
[input]
|
[input]
|
||||||
|
|
||||||
move_left={
|
move_left={
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
extends Button
|
||||||
|
|
||||||
|
@export var address: String
|
||||||
|
@export var port: int
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
text = "Connect to " + address + ":" + str(port)
|
|
@ -0,0 +1,2 @@
|
||||||
|
extends Node
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
@export var address: String
|
||||||
|
@export var port: int
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
var m = SceneMultiplayer.new()
|
||||||
|
get_tree().set_multiplayer(m, get_path())
|
||||||
|
var peer := ENetMultiplayerPeer.new()
|
||||||
|
peer.create_client(address, port)
|
||||||
|
m.multiplayer_peer = peer
|
||||||
|
m.connected_to_server.connect(connected_to_server)
|
||||||
|
|
||||||
|
func connected_to_server():
|
||||||
|
print("Client connected to server")
|
|
@ -0,0 +1,9 @@
|
||||||
|
[gd_scene load_steps=3 format=3 uid="uid://cb5t0uw0nr5bg"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://server/client.gd" id="1_frcvp"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://b00brfkibo5cj" path="res://level/level.tscn" id="2_eigcb"]
|
||||||
|
|
||||||
|
[node name="Client" type="Node"]
|
||||||
|
script = ExtResource("1_frcvp")
|
||||||
|
|
||||||
|
[node name="level" parent="." instance=ExtResource("2_eigcb")]
|
|
@ -0,0 +1,25 @@
|
||||||
|
extends Control
|
||||||
|
|
||||||
|
var address: String
|
||||||
|
var port: int
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
var m = SceneMultiplayer.new()
|
||||||
|
get_tree().set_multiplayer(m, %LobbyList.get_path())
|
||||||
|
var peer := ENetMultiplayerPeer.new()
|
||||||
|
var error := peer.create_client(address, port)
|
||||||
|
if error:
|
||||||
|
push_error(error)
|
||||||
|
m.multiplayer_peer = peer
|
||||||
|
m.connected_to_server.connect(connected_to_server)
|
||||||
|
%LobbyList.set_multiplayer_authority(1)
|
||||||
|
|
||||||
|
func connected_to_server():
|
||||||
|
print("Connected to master server @ " + address + ":" + str(port))
|
||||||
|
|
||||||
|
func _on_lobby_list_join_lobby(join_addr, join_port):
|
||||||
|
queue_free()
|
||||||
|
var client := preload("res://server/client.tscn").instantiate()
|
||||||
|
client.address = join_addr
|
||||||
|
client.port = join_port
|
||||||
|
get_parent().add_child(client)
|
|
@ -0,0 +1,27 @@
|
||||||
|
[gd_scene load_steps=3 format=3 uid="uid://d3i1pstq13h2p"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://server/client_lobbies.gd" id="1_2hyqo"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://bdfsbuxqrkq68" path="res://server/lobby_list.tscn" id="2_rktrq"]
|
||||||
|
|
||||||
|
[node name="Server" type="Control"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = ExtResource("1_2hyqo")
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="."]
|
||||||
|
layout_mode = 0
|
||||||
|
offset_right = 40.0
|
||||||
|
offset_bottom = 23.0
|
||||||
|
text = "Lobby List:"
|
||||||
|
|
||||||
|
[node name="LobbyList" parent="." instance=ExtResource("2_rktrq")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 1
|
||||||
|
|
||||||
|
[connection signal="join_lobby" from="LobbyList" to="." method="_on_lobby_list_join_lobby"]
|
||||||
|
|
||||||
|
[editable path="LobbyList"]
|
|
@ -0,0 +1,16 @@
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
var port: int
|
||||||
|
var MAX_CLIENTS := 32
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
var m = SceneMultiplayer.new()
|
||||||
|
get_tree().set_multiplayer(m, get_path())
|
||||||
|
var peer := ENetMultiplayerPeer.new()
|
||||||
|
peer.create_server(port, MAX_CLIENTS)
|
||||||
|
m.multiplayer_peer = peer
|
||||||
|
m.peer_connected.connect(peer_connected)
|
||||||
|
|
||||||
|
func peer_connected(id: int):
|
||||||
|
print("Client " + str(id) + "connected to lobby " + str(get_path()))
|
||||||
|
$level.server_add_player(id)
|
|
@ -0,0 +1,9 @@
|
||||||
|
[gd_scene load_steps=3 format=3 uid="uid://tilcdm56kb10"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://server/lobby.gd" id="1_cpwsy"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://b00brfkibo5cj" path="res://level/level.tscn" id="2_mulf5"]
|
||||||
|
|
||||||
|
[node name="Lobby" type="Node"]
|
||||||
|
script = ExtResource("1_cpwsy")
|
||||||
|
|
||||||
|
[node name="level" parent="." instance=ExtResource("2_mulf5")]
|
|
@ -0,0 +1,17 @@
|
||||||
|
extends Control
|
||||||
|
|
||||||
|
signal join_lobby(addr: String, port: int)
|
||||||
|
|
||||||
|
@rpc("reliable", "authority", "call_local")
|
||||||
|
func add(addr: String, port: int):
|
||||||
|
var lobby_button := preload("res://server/lobby_list_entry.tscn").instantiate()
|
||||||
|
lobby_button.address = addr
|
||||||
|
lobby_button.port = port
|
||||||
|
$Lobbies.add_child(lobby_button, true)
|
||||||
|
lobby_button.pressed.connect(emit_join_lobby.bind(addr, port))
|
||||||
|
|
||||||
|
func emit_join_lobby(addr: String, port: int):
|
||||||
|
join_lobby.emit(addr, port)
|
||||||
|
|
||||||
|
func lobbies():
|
||||||
|
return $Lobbies.get_children()
|
|
@ -0,0 +1,21 @@
|
||||||
|
[gd_scene load_steps=2 format=3 uid="uid://bdfsbuxqrkq68"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://server/lobby_list.gd" id="1_tktrj"]
|
||||||
|
|
||||||
|
[node name="LobbyList" type="Control"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_top = 67.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = ExtResource("1_tktrj")
|
||||||
|
|
||||||
|
[node name="Lobbies" type="VBoxContainer" parent="."]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
|
@ -0,0 +1,6 @@
|
||||||
|
[gd_scene load_steps=2 format=3 uid="uid://mhnsc0w6xt85"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://server/LobbyListEntry.gd" id="1_su4dr"]
|
||||||
|
|
||||||
|
[node name="LobbyListEntry" type="Button"]
|
||||||
|
script = ExtResource("1_su4dr")
|
|
@ -0,0 +1,4 @@
|
||||||
|
Two types of servers / clients
|
||||||
|
One for lobby management and one for actual game
|
||||||
|
server.gd and client_lobbies.gd handle the former
|
||||||
|
and lobby.gd and client.gd handle the latter
|
|
@ -0,0 +1,31 @@
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
@export var external_address := "127.0.0.1"
|
||||||
|
var master_server_port := 3000
|
||||||
|
var next_port_num := master_server_port + 1
|
||||||
|
const MAX_CLIENTS = 4095
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
var m = SceneMultiplayer.new()
|
||||||
|
get_tree().set_multiplayer(m, %LobbyList.get_path())
|
||||||
|
var peer := ENetMultiplayerPeer.new()
|
||||||
|
var error := peer.create_server(master_server_port, MAX_CLIENTS)
|
||||||
|
if error:
|
||||||
|
push_error(error)
|
||||||
|
m.multiplayer_peer = peer
|
||||||
|
m.peer_connected.connect(peer_connected)
|
||||||
|
|
||||||
|
func peer_connected(id: int):
|
||||||
|
print("Client " + str(id) + " connected to master server")
|
||||||
|
for lobby in %LobbyList.lobbies():
|
||||||
|
%LobbyList.add.rpc_id(id, lobby.address, lobby.port)
|
||||||
|
|
||||||
|
func create_lobby():
|
||||||
|
var lobby := preload("res://server/lobby.tscn").instantiate()
|
||||||
|
lobby.port = next_port_num
|
||||||
|
next_port_num += 1
|
||||||
|
%Lobbies.add_child(lobby)
|
||||||
|
%LobbyList.add.rpc(external_address, lobby.port)
|
||||||
|
|
||||||
|
func _on_create_lobby_pressed():
|
||||||
|
create_lobby()
|
|
@ -0,0 +1,29 @@
|
||||||
|
[gd_scene load_steps=3 format=3 uid="uid://cb6qjcj72sfe2"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://server/server.gd" id="1_0oac5"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://bdfsbuxqrkq68" path="res://server/lobby_list.tscn" id="2_mxbok"]
|
||||||
|
|
||||||
|
[node name="Server" type="Node"]
|
||||||
|
script = ExtResource("1_0oac5")
|
||||||
|
|
||||||
|
[node name="DebugControls" type="Control" parent="."]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
|
||||||
|
[node name="CreateLobby" type="Button" parent="DebugControls"]
|
||||||
|
layout_mode = 0
|
||||||
|
offset_right = 8.0
|
||||||
|
offset_bottom = 8.0
|
||||||
|
text = "Create Lobby"
|
||||||
|
|
||||||
|
[node name="LobbyList" parent="." instance=ExtResource("2_mxbok")]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
|
||||||
|
[node name="Lobbies" type="Node" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
|
||||||
|
[connection signal="pressed" from="DebugControls/CreateLobby" to="." method="_on_create_lobby_pressed"]
|
Loading…
Reference in New Issue