From 591225996d4214079c6ca617b95b0e713c129c7a Mon Sep 17 00:00:00 2001 From: Thayol Date: Wed, 19 Feb 2025 22:23:35 +0900 Subject: [PATCH] add chasers --- materials/chaser.tres | 4 + scenes/chaser.tscn | 120 +++++++++++++++++++++ scenes/in_game.tscn | 9 +- scenes/main_menu.tscn | 26 ++++- scripts/in_game.gd | 12 ++- scripts/main_menu.gd | 8 +- scripts/multiplayer/multiplayer_manager.gd | 23 +++- 7 files changed, 186 insertions(+), 16 deletions(-) create mode 100644 materials/chaser.tres create mode 100644 scenes/chaser.tscn diff --git a/materials/chaser.tres b/materials/chaser.tres new file mode 100644 index 0000000..3c6607e --- /dev/null +++ b/materials/chaser.tres @@ -0,0 +1,4 @@ +[gd_resource type="StandardMaterial3D" format=3 uid="uid://diptcpjxid3cm"] + +[resource] +albedo_color = Color(0.799569, 0, 0.0857406, 1) diff --git a/scenes/chaser.tscn b/scenes/chaser.tscn new file mode 100644 index 0000000..f80b167 --- /dev/null +++ b/scenes/chaser.tscn @@ -0,0 +1,120 @@ +[gd_scene load_steps=17 format=3 uid="uid://dvqj0souma3mh"] + +[ext_resource type="Script" path="res://scripts/runner.gd" id="1_hjhpa"] +[ext_resource type="Script" path="res://scripts/multiplayer/input.gd" id="2_ktv5u"] +[ext_resource type="Material" uid="uid://diptcpjxid3cm" path="res://materials/chaser.tres" id="3_tvy4p"] +[ext_resource type="Script" path="res://scripts/states/state_machine.gd" id="4_ttxqy"] +[ext_resource type="Script" path="res://scripts/states/idle.gd" id="5_vepvv"] +[ext_resource type="Script" path="res://scripts/states/run.gd" id="6_fllo7"] +[ext_resource type="Script" path="res://scripts/states/fall.gd" id="7_0e04j"] +[ext_resource type="Script" path="res://scripts/states/walk.gd" id="8_s1mx5"] + +[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_ukf45"] +properties/0/path = NodePath(".:player_id") +properties/0/spawn = true +properties/0/replication_mode = 2 +properties/1/path = NodePath(".:server_position") +properties/1/spawn = true +properties/1/replication_mode = 2 +properties/2/path = NodePath(".:server_rotation") +properties/2/spawn = true +properties/2/replication_mode = 2 + +[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_1agtp"] +properties/0/path = NodePath("Input:direction") +properties/0/spawn = true +properties/0/replication_mode = 2 +properties/1/path = NodePath("Input:walking") +properties/1/spawn = true +properties/1/replication_mode = 2 + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_j6tb3"] +radius = 0.3 +height = 1.8 + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_di3a0"] +radius = 0.3 +height = 1.8 + +[sub_resource type="PrismMesh" id="PrismMesh_fcj1v"] + +[sub_resource type="SphereMesh" id="SphereMesh_tudvv"] + +[sub_resource type="SphereMesh" id="SphereMesh_1gltg"] + +[sub_resource type="SphereShape3D" id="SphereShape3D_wsx1k"] + +[node name="Runner" type="CharacterBody3D" node_paths=PackedStringArray("state_machine")] +script = ExtResource("1_hjhpa") +state_machine = NodePath("StateMachine") + +[node name="Sync" type="MultiplayerSynchronizer" parent="."] +replication_config = SubResource("SceneReplicationConfig_ukf45") + +[node name="Input" type="MultiplayerSynchronizer" parent="."] +unique_name_in_owner = true +replication_config = SubResource("SceneReplicationConfig_1agtp") +script = ExtResource("2_ktv5u") + +[node name="CameraPivot" type="Node3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, 0) + +[node name="Collider" type="CollisionShape3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) +shape = SubResource("CapsuleShape3D_j6tb3") + +[node name="Skin" type="Node3D" parent="."] +unique_name_in_owner = true + +[node name="MainBody" type="MeshInstance3D" parent="Skin"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) +mesh = SubResource("CapsuleMesh_di3a0") +skeleton = NodePath("../..") +surface_material_override/0 = ExtResource("3_tvy4p") + +[node name="Beak" type="MeshInstance3D" parent="Skin/MainBody"] +transform = Transform3D(0.35, 0, 0, 0, -0.105655, 0.0906308, 0, -0.226577, -0.0422618, 0, 0.45, -0.3) +mesh = SubResource("PrismMesh_fcj1v") + +[node name="RightEye" type="MeshInstance3D" parent="Skin/MainBody"] +transform = Transform3D(0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1, 0.1, 0.6, -0.25) +mesh = SubResource("SphereMesh_tudvv") + +[node name="LeftEye" type="MeshInstance3D" parent="Skin/MainBody"] +transform = Transform3D(0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1, -0.1, 0.6, -0.25) +mesh = SubResource("SphereMesh_1gltg") + +[node name="FloatingCamera" type="Node" parent="."] + +[node name="CameraPlatform" type="Node3D" parent="FloatingCamera"] +unique_name_in_owner = true + +[node name="CameraSpringArm" type="SpringArm3D" parent="FloatingCamera/CameraPlatform"] +shape = SubResource("SphereShape3D_wsx1k") +spring_length = 3.5 + +[node name="Camera" type="Camera3D" parent="FloatingCamera/CameraPlatform/CameraSpringArm"] +unique_name_in_owner = true + +[node name="StateMachine" type="Node" parent="." node_paths=PackedStringArray("current_state")] +script = ExtResource("4_ttxqy") +current_state = NodePath("Idle") + +[node name="Idle" type="Node" parent="StateMachine"] +unique_name_in_owner = true +script = ExtResource("5_vepvv") + +[node name="Run" type="Node" parent="StateMachine"] +unique_name_in_owner = true +script = ExtResource("6_fllo7") + +[node name="Fall" type="Node" parent="StateMachine"] +unique_name_in_owner = true +script = ExtResource("7_0e04j") + +[node name="Walk" type="Node" parent="StateMachine"] +unique_name_in_owner = true +script = ExtResource("8_s1mx5") + +[connection signal="delta_synchronized" from="Sync" to="." method="_on_sync_delta_synchronized"] diff --git a/scenes/in_game.tscn b/scenes/in_game.tscn index 803928d..ae5119f 100644 --- a/scenes/in_game.tscn +++ b/scenes/in_game.tscn @@ -22,7 +22,11 @@ script = ExtResource("1_0lma2") [node name="WorldEnvironment" type="WorldEnvironment" parent="."] environment = SubResource("Environment_2c67a") -[node name="MultiplayerSpawner" type="MultiplayerSpawner" parent="."] +[node name="ChaserSpawner" type="MultiplayerSpawner" parent="."] +_spawnable_scenes = PackedStringArray("res://scenes/chaser.tscn") +spawn_path = NodePath("../Chasers") + +[node name="RunnerSpawner" type="MultiplayerSpawner" parent="."] _spawnable_scenes = PackedStringArray("res://scenes/runner.tscn") spawn_path = NodePath("../Runners") @@ -37,6 +41,9 @@ surface_material_override/0 = ExtResource("2_f8uto") [node name="House" parent="." instance=ExtResource("4_38bom")] +[node name="Chasers" type="Node3D" parent="."] +unique_name_in_owner = true + [node name="Runners" type="Node3D" parent="."] unique_name_in_owner = true diff --git a/scenes/main_menu.tscn b/scenes/main_menu.tscn index eaa983f..2d83ab1 100644 --- a/scenes/main_menu.tscn +++ b/scenes/main_menu.tscn @@ -58,10 +58,28 @@ placeholder_text = "localhost (default)" custom_minimum_size = Vector2(0, 15) layout_mode = 2 -[node name="JoinButton" type="Button" parent="Panel/Center/VerticalMenu"] -custom_minimum_size = Vector2(200, 40) +[node name="JoinLabel" type="RichTextLabel" parent="Panel/Center/VerticalMenu"] +custom_minimum_size = Vector2(0, 25) layout_mode = 2 -text = "Join" +size_flags_vertical = 4 +bbcode_enabled = true +text = "[center]Join as[/center]" +scroll_active = false + +[node name="HBoxContainer" type="HBoxContainer" parent="Panel/Center/VerticalMenu"] +layout_mode = 2 + +[node name="JoinAsRunnerButton" type="Button" parent="Panel/Center/VerticalMenu/HBoxContainer"] +custom_minimum_size = Vector2(150, 40) +layout_mode = 2 +text = "Runner" text_overrun_behavior = 3 -[connection signal="pressed" from="Panel/Center/VerticalMenu/JoinButton" to="." method="_on_join_button_pressed"] +[node name="JoinAsChaserButton" type="Button" parent="Panel/Center/VerticalMenu/HBoxContainer"] +custom_minimum_size = Vector2(150, 40) +layout_mode = 2 +text = "Chaser" +text_overrun_behavior = 3 + +[connection signal="pressed" from="Panel/Center/VerticalMenu/HBoxContainer/JoinAsRunnerButton" to="." method="_on_join_as_runner_button_pressed"] +[connection signal="pressed" from="Panel/Center/VerticalMenu/HBoxContainer/JoinAsChaserButton" to="." method="_on_join_as_chaser_button_pressed"] diff --git a/scripts/in_game.gd b/scripts/in_game.gd index fd6026d..118e9c6 100644 --- a/scripts/in_game.gd +++ b/scripts/in_game.gd @@ -3,16 +3,18 @@ extends Node3D const statsTemplate := "FPS: %d\nPing: %d ms" var runner_scene := preload("res://scenes/runner.tscn") +var chaser_scene := preload("res://scenes/chaser.tscn") var _ping := 0.0 +@onready var _chasers_node: Node3D = %Chasers @onready var _runners_node: Node3D = %Runners -func spawn_player(player_id) -> void: +func spawn_player(player_id: int, runner: bool) -> void: if multiplayer.is_server(): - var runner = runner_scene.instantiate() - runner.player_id = player_id - runner.name = str(player_id) + var player = runner_scene.instantiate() if runner else chaser_scene.instantiate() + player.player_id = player_id + player.name = str(player_id) - _runners_node.add_child(runner) + _runners_node.add_child(player) if runner else _chasers_node.add_child(player) func _process(_delta: float) -> void: if DisplayServer.get_name() == "headless": diff --git a/scripts/main_menu.gd b/scripts/main_menu.gd index b937a9b..8f31173 100644 --- a/scripts/main_menu.gd +++ b/scripts/main_menu.gd @@ -1,5 +1,9 @@ extends Control -func _on_join_button_pressed() -> void: - MultiplayerManager.connect_to_ip(%IpTextBox.text) +func _on_join_as_runner_button_pressed() -> void: + MultiplayerManager.connect_to_ip(true, %IpTextBox.text) + get_tree().change_scene_to_file("res://scenes/in_game.tscn") + +func _on_join_as_chaser_button_pressed() -> void: + MultiplayerManager.connect_to_ip(false, %IpTextBox.text) get_tree().change_scene_to_file("res://scenes/in_game.tscn") diff --git a/scripts/multiplayer/multiplayer_manager.gd b/scripts/multiplayer/multiplayer_manager.gd index ba9203a..accdcd1 100644 --- a/scripts/multiplayer/multiplayer_manager.gd +++ b/scripts/multiplayer/multiplayer_manager.gd @@ -4,8 +4,10 @@ const PORT = 1280 const IP_ADDRESS = "127.0.0.1" const MAX_CLIENTS = 5 -var in_game_scene = preload("res://scenes/in_game.tscn") -var main_menu_scene = preload("res://scenes/main_menu.tscn") +var in_game_scene := preload("res://scenes/in_game.tscn") +var main_menu_scene := preload("res://scenes/main_menu.tscn") +var runner_client_selection := true +var runner_dict := {} func _ready() -> void: set_process(false) @@ -23,9 +25,11 @@ func _ready() -> void: else: get_tree().change_scene_to_packed.call_deferred(main_menu_scene) -func connect_to_ip(ip: String = "") -> void: +func connect_to_ip(runner: bool = true, ip: String = "") -> void: if ip.is_empty(): ip = IP_ADDRESS + + runner_client_selection = runner print("Connecting to: %s" % ip) @@ -39,13 +43,13 @@ func connect_to_ip(ip: String = "") -> void: func _on_connect(id: int) -> void: print("Client ID #%s connected" % id) - get_tree().get_current_scene().spawn_player(id) func _on_disconnect(id: int) -> void: print("Client ID #%s disconnected" % id) pass func _on_connect_client() -> void: + request_is_runner.rpc_id(1, runner_client_selection) print("[%s] Connected to server" % multiplayer.get_unique_id()) pass @@ -56,3 +60,14 @@ func _on_disconnect_client() -> void: func _on_server_closed_client() -> void: print("[%s] Server closed" % multiplayer.get_unique_id()) pass + +@rpc("any_peer", "call_remote", "reliable") +func request_is_runner(runner: bool) -> void: + if not multiplayer.is_server(): + return + + var id := multiplayer.get_remote_sender_id() + runner_dict[id] = runner + print("Runner Dict: %s" % runner_dict) + + get_tree().get_current_scene().spawn_player(id, runner)