From ad95c99149a544217e5943bfefc37e4a51cea292 Mon Sep 17 00:00:00 2001 From: Nikolai Rodionov Date: Thu, 6 Feb 2025 13:42:14 +0100 Subject: [PATCH] Trying to make sync work --- godot/scenes/maps/base/map_controller.gd | 11 ++-- .../base/player_spawner/player_spawner.gd | 15 ++--- .../base/player_spawner/player_spawner.tscn | 2 +- godot/scenes/player/placeholder.gd | 28 ---------- godot/scenes/player/placeholder.tscn | 13 ++++- godot/scenes/player/player_input.tscn | 6 +- ...yer_input_controller.gd => player_node.gd} | 56 +++++++++++-------- godot/scenes/player/player_node.tscn | 11 ++++ godot/scenes/player/server_node.gd | 51 +++++++++++++++++ godot/scenes/player/server_node.tscn | 27 ++++++--- godot/scenes/player/shared_node.tscn | 22 ++++++++ 11 files changed, 165 insertions(+), 77 deletions(-) delete mode 100644 godot/scenes/player/placeholder.gd rename godot/scenes/player/{player_input_controller.gd => player_node.gd} (53%) create mode 100644 godot/scenes/player/player_node.tscn create mode 100644 godot/scenes/player/server_node.gd create mode 100644 godot/scenes/player/shared_node.tscn diff --git a/godot/scenes/maps/base/map_controller.gd b/godot/scenes/maps/base/map_controller.gd index 8043c32..10265c8 100644 --- a/godot/scenes/maps/base/map_controller.gd +++ b/godot/scenes/maps/base/map_controller.gd @@ -45,19 +45,20 @@ func _process(delta: float) -> void: func _request_spawn(): var id: int = multiplayer.get_remote_sender_id() _spawn_player(id) - _spawn_player_controller_node.rpc_id(id) func _spawn_player(id: int): player_spawner.spawn_players(spawn_locations, id) + _spawn_player_controller_node.rpc_id(id) -@rpc("call_local", "reliable", "any_peer") +@rpc("any_peer", "call_local", "reliable") func _spawn_player_controller_node(): - var path := "res://scenes/player/player_input.tscn" + var path := "res://scenes/player/player_node.tscn" var scene: PackedScene = ResourceLoader.load(path) - var controller_scene: PlayerPlaceholder = player_spawner.get_player_node(multiplayer.get_unique_id()) var player_node: PlayerInputController = scene.instantiate() - player_node.controlled_node = controller_scene + var controlled_node: ServerNode = player_spawner.get_player_node(multiplayer.get_unique_id()) + player_node.controlled_node = controlled_node client_node.add_child(player_node) + player_node.initial_position_sync() func _remove_player(id: int): diff --git a/godot/scenes/maps/base/player_spawner/player_spawner.gd b/godot/scenes/maps/base/player_spawner/player_spawner.gd index 45693e7..39a0247 100644 --- a/godot/scenes/maps/base/player_spawner/player_spawner.gd +++ b/godot/scenes/maps/base/player_spawner/player_spawner.gd @@ -1,5 +1,5 @@ -class_name PlayerSpawnerController extends Node3D - +class_name PlayerSpawnerController +extends Node3D func _get_spawner() -> MultiplayerSpawner: return $MultiplayerSpawner @@ -10,14 +10,15 @@ func _get_root() -> Node3D: # -- Spawn a player node and sync it across all peers func spawn_players(spawn_location: SpawnController, id: int) -> Error: if multiplayer.is_server(): - var char : PlayerPlaceholder = null + var char : ServerNode = null var player_data: PlayerData = GameServerAutoload.players[id] - char = ResourceLoader.load("res://scenes/player/placeholder.tscn").instantiate() + char = ResourceLoader.load("res://scenes/player/server_node.tscn").instantiate() char.name = "PlayerPlaceholder_" + str(player_data.id) var new_position: Vector3 = spawn_location.get_spawner(SpawnController.Sides.BLUE) - char.global_position = new_position char.owner_id = id _get_root().add_child(char) + char.shared_node.global_position = new_position + print(new_position) return OK return ERR_UNAUTHORIZED @@ -31,8 +32,8 @@ func remove_player(id: int) -> Error: return OK return ERR_UNAUTHORIZED -func get_player_node(id: int) -> PlayerPlaceholder: - var nodes: Array[Node] = _get_root().get_children().filter(func(x: PlayerPlaceholder): return x.owner_id == id) +func get_player_node(id: int) -> ServerNode: + var nodes: Array[Node] = _get_root().get_children().filter(func(x: ServerNode): return x.owner_id == id) if nodes.size() > 0: return nodes[0] return null diff --git a/godot/scenes/maps/base/player_spawner/player_spawner.tscn b/godot/scenes/maps/base/player_spawner/player_spawner.tscn index 402bf17..6efb124 100644 --- a/godot/scenes/maps/base/player_spawner/player_spawner.tscn +++ b/godot/scenes/maps/base/player_spawner/player_spawner.tscn @@ -6,7 +6,7 @@ script = ExtResource("1_2hsyd") [node name="MultiplayerSpawner" type="MultiplayerSpawner" parent="."] -_spawnable_scenes = PackedStringArray("res://scenes/player/placeholder.tscn") +_spawnable_scenes = PackedStringArray("res://scenes/player/server_node.tscn") spawn_path = NodePath("../Players") spawn_limit = 100 diff --git a/godot/scenes/player/placeholder.gd b/godot/scenes/player/placeholder.gd deleted file mode 100644 index a632823..0000000 --- a/godot/scenes/player/placeholder.gd +++ /dev/null @@ -1,28 +0,0 @@ -extends CharacterBody3D -class_name ServerNode - -var jumping := false -var input_direction: Vector2 = null -var owner_id: int = 0 - -func _ready() -> void: - pass - -func _physics_process(delta: float) -> void: - if not is_on_floor(): - velocity += get_gravity() * delta - if is_on_floor() && jumping: - velocity.y = const . - - #if shooting: - jumping = false - - var direction := (transform.basis * Vector3(input_direction.x, 0, input_direction.y)).normalized() - if is_on_floor(): - if direction: - #first_view_legs_anim.play("Run Forward") - velocity.x = direction.x * character_speed - velocity.z = direction.z * character_speed - else: - velocity.x = move_toward(velocity.x, 0, character_speed) - velocity.z = move_toward(velocity.z, 0, character_speed) diff --git a/godot/scenes/player/placeholder.tscn b/godot/scenes/player/placeholder.tscn index c9f06b8..6524316 100644 --- a/godot/scenes/player/placeholder.tscn +++ b/godot/scenes/player/placeholder.tscn @@ -1,6 +1,6 @@ -[gd_scene load_steps=5 format=3 uid="uid://3m22sdln5238"] +[gd_scene load_steps=5 format=3 uid="uid://cwqhnknctn83"] -[ext_resource type="Script" path="res://scenes/player/placeholder.gd" id="1_djt0m"] +[ext_resource type="Script" path="res://scenes/player/server_node.gd" id="1_djt0m"] [ext_resource type="PackedScene" uid="uid://ddwrs0so7swxn" path="res://scenes/characters/y-bot/character.tscn" id="2_a22jl"] [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_1v0rt"] @@ -15,6 +15,15 @@ properties/1/spawn = true properties/1/replication_mode = 1 [node name="PlayerPlaceholder" type="PlayerPlaceholder"] +_import_path = NodePath("") +unique_name_in_owner = false +process_mode = 0 +process_priority = 0 +process_physics_priority = 0 +process_thread_group = 0 +physics_interpolation_mode = 0 +auto_translate_mode = 0 +editor_description = "" collision_layer = 4 collision_mask = 5 script = ExtResource("1_djt0m") diff --git a/godot/scenes/player/player_input.tscn b/godot/scenes/player/player_input.tscn index ab53075..8332f51 100644 --- a/godot/scenes/player/player_input.tscn +++ b/godot/scenes/player/player_input.tscn @@ -1,13 +1,13 @@ -[gd_scene load_steps=3 format=3 uid="uid://dqp551myngaey"] +[gd_scene load_steps=3 format=3 uid="uid://d3ohhfsnbspsm"] -[ext_resource type="Script" path="res://scenes/player/player_input_controller.gd" id="1_5vm0e"] +[ext_resource type="Script" path="res://scenes/player/player_node.gd" id="1_8uxms"] [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_uacs5"] [node name="PlayerInput" type="CharacterBody3D"] collision_layer = 2 collision_mask = 3 -script = ExtResource("1_5vm0e") +script = ExtResource("1_8uxms") [node name="CollisionShape3D" type="CollisionShape3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) diff --git a/godot/scenes/player/player_input_controller.gd b/godot/scenes/player/player_node.gd similarity index 53% rename from godot/scenes/player/player_input_controller.gd rename to godot/scenes/player/player_node.gd index 96f6ab2..a6fcffe 100644 --- a/godot/scenes/player/player_input_controller.gd +++ b/godot/scenes/player/player_node.gd @@ -2,27 +2,37 @@ # This script is supposed to control the node that is rendered on the # client side, and send the changes to the server node # --------------------------------------------------------------------- -extends CharacterBody3D +extends Node3D class_name PlayerInputController var jumping: bool = false var shooting: bool = false var moving: bool = false var look_dir: Vector2 -var input_direction := Vector2() +var input_direction: Vector2 var camera_sens: float = 0.002 const JUMP_VELOCITY = 4.5 var character_speed: int = 5 -var controlled_node: PlayerPlaceholder = null -@export var owner_id: int = 0 +var controlled_node: ServerNode = null +@export var owner_id: int + +@onready var shared_node: CharacterBody3D = $SharedNode +@onready var camera_mount: Node3D = $SharedNode/CameraMount +@onready var camera: Camera3D = $SharedNode/CameraMount/Camera3D -@onready var camera_mount = $CameraMount func _ready() -> void: set_multiplayer_authority(multiplayer.get_unique_id()) - global_position = controlled_node.global_position - rotation = controlled_node.rotation + shared_node.set_collision_layer_value(2, true) + shared_node.set_collision_mask_value(1, true) + shared_node.set_collision_mask_value(2, true) + camera.make_current() + +func initial_position_sync(): + + shared_node.global_position = controlled_node.shared_node.global_position + shared_node.rotation = controlled_node.shared_node.rotation func _input(event): if multiplayer.get_unique_id() == get_multiplayer_authority(): @@ -30,14 +40,15 @@ func _input(event): if Input.is_action_just_released("shoot"): shooting = false if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED: look_dir = event.relative * 1 - rotation.y -= look_dir.x * camera_sens * 1.0 + shared_node.rotation.y -= look_dir.x * camera_sens * 1.0 camera_mount.rotation.x = clamp(camera_mount.rotation.x - look_dir.y * camera_sens * 1.0, -1.5, 1.5) - controlled_node.set_rotation_x.rpc_id(1, rotation.x) - controlled_node.set_rotation_y.rpc_id(1, rotation.y) + controlled_node.set_rotation_x.rpc_id(1, shared_node.rotation.x) + controlled_node.set_rotation_y.rpc_id(1, shared_node.rotation.y) if Input.is_action_pressed("move_left") or Input.is_action_pressed("move_right") or Input.is_action_pressed("move_forward") or Input.is_action_pressed("move_backwards"): moving = true else: moving = false + input_direction = Input.get_vector("move_left", "move_right", "move_forward", "move_backward") func jump(): jumping = true @@ -46,27 +57,26 @@ func jump(): func _physics_process(delta: float) -> void: if multiplayer.get_unique_id() == get_multiplayer_authority(): Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) - input_direction = Input.get_vector("move_left", "move_right", "move_forward", "move_backward") + controlled_node.set_input_direction.rpc_id(1, input_direction) - if not is_on_floor(): - velocity += get_gravity() * delta - if is_on_floor() && jumping: - velocity.y = JUMP_VELOCITY + if not shared_node.is_on_floor(): + shared_node.velocity += shared_node.get_gravity() * delta + if shared_node.is_on_floor() && jumping: + shared_node.velocity.y = consts.DEFAULT_JUMP_VELOCITY #if shooting: jumping = false - var direction := (transform.basis * Vector3(input_direction.x, 0, input_direction.y)).normalized() - if is_on_floor(): + var direction := (shared_node.transform.basis * Vector3(input_direction.x, 0, input_direction.y)).normalized() + if shared_node.is_on_floor(): if direction: #first_view_legs_anim.play("Run Forward") - velocity.x = direction.x * character_speed - velocity.z = direction.z * character_speed + shared_node.velocity.x = direction.x * consts.DEFAULT_CHARACTER_SPEED + shared_node.velocity.z = direction.z * consts.DEFAULT_CHARACTER_SPEED else: - velocity.x = move_toward(velocity.x, 0, character_speed) - velocity.z = move_toward(velocity.z, 0, character_speed) - #controlled_node.sync_velocity.rpc_id(1, velocity.x, velocity.y, velocity.z) + shared_node.velocity.x = move_toward(shared_node.velocity.x, 0, consts.DEFAULT_CHARACTER_SPEED) + shared_node.velocity.z = move_toward(shared_node.velocity.z, 0, consts.DEFAULT_CHARACTER_SPEED) func _process(delta: float) -> void: - move_and_slide() + shared_node.move_and_slide() diff --git a/godot/scenes/player/player_node.tscn b/godot/scenes/player/player_node.tscn new file mode 100644 index 0000000..a57085b --- /dev/null +++ b/godot/scenes/player/player_node.tscn @@ -0,0 +1,11 @@ +[gd_scene load_steps=3 format=3 uid="uid://conlvf1vqni6c"] + +[ext_resource type="Script" path="res://scenes/player/player_node.gd" id="1_q00bg"] +[ext_resource type="PackedScene" uid="uid://cirun2v34nfpg" path="res://scenes/player/shared_node.tscn" id="2_4mkad"] + +[node name="PlayerNode" type="Node3D"] +script = ExtResource("1_q00bg") + +[node name="SharedNode" parent="." instance=ExtResource("2_4mkad")] + +[node name="CSGSphere3D" type="CSGSphere3D" parent="."] diff --git a/godot/scenes/player/server_node.gd b/godot/scenes/player/server_node.gd new file mode 100644 index 0000000..5cc41f8 --- /dev/null +++ b/godot/scenes/player/server_node.gd @@ -0,0 +1,51 @@ +extends Node3D +class_name ServerNode + +var jumping := false +var input_direction: Vector2 +@export var owner_id: int = 0 + +@onready var camera_mount: Node3D = $SharedNode/CameraMount +@onready var shared_node: CharacterBody3D = $SharedNode + +func _ready() -> void: + shared_node.set_collision_layer_value(3, true) + shared_node.set_collision_mask_value(1, true) + shared_node.set_collision_mask_value(3, true) + # Deploy a local controller node +func _physics_process(delta: float) -> void: + if not shared_node.is_on_floor(): + shared_node.velocity += shared_node.get_gravity() * delta + if shared_node.is_on_floor() && jumping: + shared_node.velocity.y = consts.DEFAULT_JUMP_VELOCITY + + + #if shooting: + jumping = false + + var direction := (shared_node.transform.basis * Vector3(input_direction.x, 0, input_direction.y)).normalized() + if shared_node.is_on_floor(): + if direction: + #first_view_legs_anim.play("Run Forward") + shared_node.velocity.x = direction.x * consts.DEFAULT_CHARACTER_SPEED + shared_node.velocity.z = direction.z * consts.DEFAULT_CHARACTER_SPEED + else: + shared_node.velocity.x = move_toward(shared_node.velocity.x, 0, consts.DEFAULT_CHARACTER_SPEED) + shared_node.velocity.z = move_toward(shared_node.velocity.z, 0, consts.DEFAULT_CHARACTER_SPEED) + shared_node.move_and_slide() + +@rpc("any_peer", "call_local", "unreliable") +func jump(): + jumping = true + +@rpc("any_peer", "call_local", "unreliable") +func set_input_direction(new_input_direction: Vector2): + input_direction = new_input_direction + +@rpc("any_peer", "call_local", "unreliable") +func set_rotation_x(x: float): + camera_mount.rotation.x = x + +@rpc("any_peer", "call_local", "unreliable") +func set_rotation_y(y: float): + shared_node.rotation.y = y diff --git a/godot/scenes/player/server_node.tscn b/godot/scenes/player/server_node.tscn index e7bc992..f0639ec 100644 --- a/godot/scenes/player/server_node.tscn +++ b/godot/scenes/player/server_node.tscn @@ -1,12 +1,23 @@ -[gd_scene load_steps=3 format=3 uid="uid://cse87uxvcvhee"] +[gd_scene load_steps=4 format=3 uid="uid://clq0b7tbincut"] -[ext_resource type="Script" path="res://scenes/player/placeholder.gd" id="1_cs2mj"] +[ext_resource type="Script" path="res://scenes/player/server_node.gd" id="1_bau14"] +[ext_resource type="PackedScene" uid="uid://cirun2v34nfpg" path="res://scenes/player/shared_node.tscn" id="1_ybp5y"] -[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_82tpl"] +[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_2dhi2"] +properties/0/path = NodePath("SharedNode:position") +properties/0/spawn = true +properties/0/replication_mode = 1 +properties/1/path = NodePath("SharedNode:rotation") +properties/1/spawn = true +properties/1/replication_mode = 1 +properties/2/path = NodePath(".:owner_id") +properties/2/spawn = true +properties/2/replication_mode = 1 -[node name="ServerNode" type="CharacterBody3D"] -script = ExtResource("1_cs2mj") +[node name="ServerNode" type="Node3D"] +script = ExtResource("1_bau14") -[node name="CollisionShape3D" type="CollisionShape3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) -shape = SubResource("CapsuleShape3D_82tpl") +[node name="SharedNode" parent="." instance=ExtResource("1_ybp5y")] + +[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."] +replication_config = SubResource("SceneReplicationConfig_2dhi2") diff --git a/godot/scenes/player/shared_node.tscn b/godot/scenes/player/shared_node.tscn new file mode 100644 index 0000000..296fd4d --- /dev/null +++ b/godot/scenes/player/shared_node.tscn @@ -0,0 +1,22 @@ +[gd_scene load_steps=2 format=3 uid="uid://cirun2v34nfpg"] + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_r38x6"] +height = 1.8 + +[node name="SharedNode" type="CharacterBody3D"] +collision_layer = 0 +collision_mask = 0 + +[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.9, 0) +shape = SubResource("CapsuleShape3D_r38x6") + +[node name="CameraMount" type="Node3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.6036, 2.18128) + +[node name="Camera3D" type="Camera3D" parent="CameraMount"] + +[node name="BulletStartingPoint" type="Node3D" parent="CameraMount"] + +[node name="CSGBox3D" type="CSGBox3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)