diff --git a/autoloads/game.gd b/autoloads/game.gd index 989bc945..46661694 100644 --- a/autoloads/game.gd +++ b/autoloads/game.gd @@ -1,4 +1,3 @@ -class_name Game extends Node signal players_updated @@ -41,6 +40,7 @@ func _ready() -> void: _initial_window_scale_aspect = get_window().content_scale_aspect get_window().size_changed.connect(_handle_size_changed) + _is_window_small = get_window().size.x < 1280 or get_window().size.y < 720 _update_window_scale() get_tree().node_added.connect(_handle_node_added) diff --git a/autoloads/game.tscn b/autoloads/game.tscn index 572d2198..78acab25 100644 --- a/autoloads/game.tscn +++ b/autoloads/game.tscn @@ -2,26 +2,29 @@ [ext_resource type="Script" uid="uid://c8lsyb801m532" path="res://autoloads/game.gd" id="1_fmbhi"] [ext_resource type="Script" uid="uid://bnqpng0o60r43" path="res://scripts/player_data_resource.gd" id="2_xaonh"] +[ext_resource type="PackedScene" uid="uid://cd04h7rme3lld" path="res://scene/Level test.tscn" id="3_du0e2"] -[sub_resource type="Resource" id="Resource_nviqh"] +[sub_resource type="Resource" id="Resource_hihc8"] script = ExtResource("2_xaonh") -name = "server" -role = 1 +name = "Test 1" +metadata/_custom_type_script = "uid://bnqpng0o60r43" -[sub_resource type="Resource" id="Resource_ckjww"] +[sub_resource type="Resource" id="Resource_du0e2"] script = ExtResource("2_xaonh") -name = "client" -role = 2 +name = "Test 2" +metadata/_custom_type_script = "uid://bnqpng0o60r43" -[sub_resource type="Resource" id="Resource_a7hko"] +[sub_resource type="Resource" id="Resource_g4v7s"] script = ExtResource("2_xaonh") -name = "client 2" -role = 3 +name = "Test 3" +metadata/_custom_type_script = "uid://bnqpng0o60r43" [node name="Game" type="Node" unique_id=369504755] script = ExtResource("1_fmbhi") +multiplayer_test = true all_roles = false -test_players = Array[ExtResource("2_xaonh")]([SubResource("Resource_nviqh"), SubResource("Resource_ckjww"), SubResource("Resource_a7hko")]) +test_players = Array[ExtResource("2_xaonh")]([SubResource("Resource_hihc8"), SubResource("Resource_du0e2"), SubResource("Resource_g4v7s")]) +main_scene = ExtResource("3_du0e2") [node name="CanvasLayer" type="CanvasLayer" parent="." unique_id=1737081465] layer = 127 diff --git a/autoloads/lobby.gd b/autoloads/lobby.gd index 0d6c7263..ffe978e3 100644 --- a/autoloads/lobby.gd +++ b/autoloads/lobby.gd @@ -1,4 +1,3 @@ -class_name Lobby extends Node static var instance: Lobby diff --git a/icon.svg.import b/icon.svg.import index 254942b0..135da236 100644 --- a/icon.svg.import +++ b/icon.svg.import @@ -3,19 +3,20 @@ importer="texture" type="CompressedTexture2D" uid="uid://tw8t38ns0seh" -path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" +path.s3tc="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.s3tc.ctex" metadata={ -"vram_texture": false +"imported_formats": ["s3tc_bptc"], +"vram_texture": true } [deps] source_file="res://icon.svg" -dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] +dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.s3tc.ctex"] [params] -compress/mode=0 +compress/mode=2 compress/high_quality=false compress/lossy_quality=0.7 compress/uastc_level=0 @@ -23,7 +24,7 @@ compress/rdo_quality_loss=0.0 compress/hdr_compression=1 compress/normal_map=0 compress/channel_pack=0 -mipmaps/generate=false +mipmaps/generate=true mipmaps/limit=-1 roughness/mode=0 roughness/src_normal="" @@ -37,7 +38,7 @@ process/normal_map_invert_y=false process/hdr_as_srgb=false process/hdr_clamp_exposure=false process/size_limit=0 -detect_3d/compress_to=1 +detect_3d/compress_to=0 svg/scale=1.0 editor/scale_with_editor_scale=false editor/convert_colors_with_editor_theme=false diff --git a/input_synchronizer.gd b/input_synchronizer.gd new file mode 100644 index 00000000..017f1057 --- /dev/null +++ b/input_synchronizer.gd @@ -0,0 +1,22 @@ +class_name InputSynchronizer + +extends MultiplayerSynchronizer + +@export var move_input: Vector2 +@export var jump: bool + + +func _physics_process(delta: float) -> void: + if not is_multiplayer_authority(): + return + + move_input = Input.get_vector("move_left", "move_right", "move_forward", "move_backward") + + if Input.is_action_just_pressed("jump"): + broadcast_jump.rpc() + + + +@rpc("call_local") +func broadcast_jump() -> void: + jump = true diff --git a/input_synchronizer.gd.uid b/input_synchronizer.gd.uid new file mode 100644 index 00000000..3a88821f --- /dev/null +++ b/input_synchronizer.gd.uid @@ -0,0 +1 @@ +uid://4p2330x1wlmr diff --git a/input_synchronizer.tscn b/input_synchronizer.tscn new file mode 100644 index 00000000..0e8d9cb5 --- /dev/null +++ b/input_synchronizer.tscn @@ -0,0 +1,12 @@ +[gd_scene format=3 uid="uid://c4ydhc8tdeu62"] + +[ext_resource type="Script" uid="uid://4p2330x1wlmr" path="res://input_synchronizer.gd" id="1_ctb74"] + +[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_vtqle"] +properties/0/path = NodePath("InputSynchronizer:move_input") +properties/0/spawn = true +properties/0/replication_mode = 1 + +[node name="InputSynchronizer" type="MultiplayerSynchronizer" unique_id=1846375910] +replication_config = SubResource("SceneReplicationConfig_vtqle") +script = ExtResource("1_ctb74") diff --git a/players/player.gd b/players/player.gd new file mode 100644 index 00000000..158a92e6 --- /dev/null +++ b/players/player.gd @@ -0,0 +1,90 @@ +extends CharacterBody3D + +@export var move_speed: float = 5 +@export var jump_speed: float = 7 +@export var acceleration: float = 20 +@export var mouse_sensitivity: float = 0.05 +@export var camera_min_pitch: float = -20 +@export var camera_max_pitch: float = 30 + +@onready var label_3d: Label3D = $Label3D +@onready var input_synchronizer: InputSynchronizer = $InputSynchronizer +@onready var sync_timer: Timer = $SyncTimer +@onready var model: Node3D = $Model +@onready var camera_pivot: Node3D = $CameraPivot +@onready var spring_arm_3d: SpringArm3D = $CameraPivot/SpringArm3D +@onready var camera_3d: Camera3D = $CameraPivot/SpringArm3D/Camera3D + + +func _ready() -> void: + sync_timer.timeout.connect(_on_sync_timeout) + +func _input(event: InputEvent) -> void: + if event.is_action_pressed("test"): + test.rpc() + +func _unhandled_input(event: InputEvent) -> void: + if not is_multiplayer_authority(): + return + var mouse_motion: InputEventMouseMotion = event as InputEventMouseMotion + if mouse_motion: + camera_pivot.rotation.y -= mouse_motion.relative.x * mouse_sensitivity + camera_pivot.rotation.x = clamp( + camera_pivot.rotation.x - mouse_motion.relative.y * mouse_sensitivity, + deg_to_rad(camera_min_pitch), deg_to_rad(camera_max_pitch)) + model.rotation.y = lerp_angle(model.rotation.y, camera_pivot.rotation.y, 1) + + +func setup(player_data: Statics.PlayerData) -> void: + label_3d.text = player_data.name + set_multiplayer_authority(player_data.id) + camera_3d.current = is_multiplayer_authority() + sync_timer.start() + + +@rpc("call_local") +func test() -> void: + var current_player: String = Game.get_current_player().name + Debug.log(current_player, 10) + + + +func _physics_process(delta: float) -> void: + + if not is_on_floor(): + velocity += get_gravity() * delta + + if is_on_floor() and input_synchronizer.jump: + velocity.y = jump_speed + input_synchronizer.jump = false + + var move_input: Vector2 = input_synchronizer.move_input + + var direction: Vector3 = model.transform.basis * Vector3(move_input.x, 0, move_input.y) + + var target: Vector2 = Vector2(direction.x, direction.z) * move_speed + var current_speed: Vector2 = Vector2(velocity.x, velocity.z) + var result: Vector2 = current_speed.move_toward(target, acceleration * delta) + + velocity.x = result.x + velocity.z = result.y + + move_and_slide() + + + #send_data.rpc(global_position) + + +#@rpc("call_remote", "unreliable_ordered") +#func send_data(pos: Vector3) -> void: +# global_position = pos + + + +func _on_sync_timeout() -> void: + _sync(global_position, velocity) + + +func _sync(pos: Vector3, vel: Vector3) -> void: + global_position = global_position.lerp(pos, 0.5) + velocity = velocity.lerp(vel, 0.5) diff --git a/players/player.gd.uid b/players/player.gd.uid new file mode 100644 index 00000000..2ad3ec2a --- /dev/null +++ b/players/player.gd.uid @@ -0,0 +1 @@ +uid://bqy2hlpq16utr diff --git a/players/player.tscn b/players/player.tscn new file mode 100644 index 00000000..85b4fce2 --- /dev/null +++ b/players/player.tscn @@ -0,0 +1,55 @@ +[gd_scene format=3 uid="uid://itg32ygcx6nc"] + +[ext_resource type="Script" uid="uid://bqy2hlpq16utr" path="res://players/player.gd" id="1_l271l"] +[ext_resource type="PackedScene" uid="uid://c4ydhc8tdeu62" path="res://input_synchronizer.tscn" id="2_i6aj8"] + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_iwpo4"] + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_bu0v1"] + +[sub_resource type="BoxMesh" id="BoxMesh_g4v7s"] +size = Vector3(0.41937256, 0.14294434, 0.84033203) + +[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_i6aj8"] +properties/0/path = NodePath("Model:rotation") +properties/0/spawn = true +properties/0/replication_mode = 1 + +[node name="Player" type="CharacterBody3D" unique_id=1611180337] +script = ExtResource("1_l271l") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=525107169] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.4563465, 0) +shape = SubResource("CapsuleShape3D_iwpo4") + +[node name="Label3D" type="Label3D" parent="." unique_id=915895812] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.6557393, 0) +billboard = 1 +text = "Player 1" + +[node name="InputSynchronizer" parent="." unique_id=1846375910 instance=ExtResource("2_i6aj8")] + +[node name="SyncTimer" type="Timer" parent="." unique_id=1686214178] +wait_time = 0.1 + +[node name="Model" type="Node3D" parent="." unique_id=1638909321] + +[node name="MeshInstance3D" type="MeshInstance3D" parent="Model" unique_id=2008098503] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.4413216, 0) +mesh = SubResource("CapsuleMesh_bu0v1") +skeleton = NodePath("../..") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="Model/MeshInstance3D" unique_id=1559359979] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5815146, -0.30548984) +mesh = SubResource("BoxMesh_g4v7s") + +[node name="CameraPivot" type="Node3D" parent="." unique_id=810192007] + +[node name="SpringArm3D" type="SpringArm3D" parent="CameraPivot" unique_id=1478529418] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 3.07, 0) +spring_length = 3.0 + +[node name="Camera3D" type="Camera3D" parent="CameraPivot/SpringArm3D" unique_id=936902903] + +[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="." unique_id=332628892] +replication_config = SubResource("SceneReplicationConfig_i6aj8") diff --git a/project.godot b/project.godot index df69d35f..52f7ed48 100644 --- a/project.godot +++ b/project.godot @@ -14,16 +14,17 @@ compatibility/default_parent_skeleton_in_mesh_instance_3d=true [application] -config/name="multiplayer_example" +config/name="Real_Engine" run/main_scene="res://ui/main_menu.tscn" config/features=PackedStringArray("4.7", "Forward Plus") +run/max_fps=180 config/icon="res://icon.svg" [autoload] Debug="*res://autoloads/debug.gd" -Game="res://autoloads/game.tscn" -Lobby="res://autoloads/lobby.tscn" +Game="*res://autoloads/game.tscn" +Lobby="*res://autoloads/lobby.tscn" [debug] @@ -45,6 +46,31 @@ test={ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":70,"key_label":0,"unicode":102,"location":0,"echo":false,"script":null) ] } +move_left={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null) +] +} +move_right={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null) +] +} +move_forward={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null) +] +} +move_backward={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null) +] +} +jump={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null) +] +} [rendering] diff --git a/scene/Level test.tscn b/scene/Level test.tscn new file mode 100644 index 00000000..821034a0 --- /dev/null +++ b/scene/Level test.tscn @@ -0,0 +1,59 @@ +[gd_scene format=3 uid="uid://cd04h7rme3lld"] + +[ext_resource type="Texture2D" uid="uid://tw8t38ns0seh" path="res://icon.svg" id="1_e7s2s"] +[ext_resource type="Script" uid="uid://bdlvueh6n00lr" path="res://scene/level_test.gd" id="1_s2pad"] +[ext_resource type="PackedScene" uid="uid://itg32ygcx6nc" path="res://players/player.tscn" id="2_2tnkg"] + +[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_e7s2s"] +sky_horizon_color = Color(0.66224277, 0.6717428, 0.6867428, 1) +ground_horizon_color = Color(0.66224277, 0.6717428, 0.6867428, 1) + +[sub_resource type="Sky" id="Sky_s2pad"] +sky_material = SubResource("ProceduralSkyMaterial_e7s2s") + +[sub_resource type="Environment" id="Environment_2tnkg"] +background_mode = 2 +sky = SubResource("Sky_s2pad") +glow_enabled = true + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_s2pad"] +albedo_texture = ExtResource("1_e7s2s") + +[sub_resource type="PlaneMesh" id="PlaneMesh_yf5fn"] + +[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_g4v7s"] + +[node name="Level1" type="Node3D" unique_id=1612030300] +script = ExtResource("1_s2pad") +player_scene = ExtResource("2_2tnkg") + +[node name="WorldEnvironment" type="WorldEnvironment" parent="." unique_id=836779784] +environment = SubResource("Environment_2tnkg") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="." unique_id=1234322734] +transform = Transform3D(-0.8660254, -0.43301278, 0.25, 0, 0.49999997, 0.86602545, -0.50000006, 0.75, -0.43301266, 0, 0, 0) +shadow_enabled = true + +[node name="StaticBody3D" type="StaticBody3D" parent="." unique_id=1968132458] +transform = Transform3D(5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0) + +[node name="MeshInstance3D" type="MeshInstance3D" parent="StaticBody3D" unique_id=1590636567] +transform = Transform3D(10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0) +material_override = SubResource("StandardMaterial3D_s2pad") +mesh = SubResource("PlaneMesh_yf5fn") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticBody3D" unique_id=416658440] +shape = SubResource("WorldBoundaryShape3D_g4v7s") + +[node name="SpawnPoints" type="Node3D" parent="." unique_id=24599143] + +[node name="Marker3D" type="Marker3D" parent="SpawnPoints" unique_id=1564069331] +transform = Transform3D(3.01, 0, 0, 0, 3.01, 0, 0, 0, 3.01, 3.134027, 0.42469287, 1.5206842) + +[node name="Marker3D2" type="Marker3D" parent="SpawnPoints" unique_id=1106538207] +transform = Transform3D(3.01, 0, 0, 0, 3.01, 0, 0, 0, 3.01, 0.10755205, 0.42469287, 4.6004534) + +[node name="Marker3D3" type="Marker3D" parent="SpawnPoints" unique_id=424434078] +transform = Transform3D(3.01, 0, 0, 0, 3.01, 0, 0, 0, 3.01, -2.9540184, 0.42469287, 1.5206842) + +[node name="Players" type="Node3D" parent="." unique_id=165699269] diff --git a/scene/level_test.gd b/scene/level_test.gd new file mode 100644 index 00000000..bc7d76dc --- /dev/null +++ b/scene/level_test.gd @@ -0,0 +1,19 @@ +extends Node3D + +@export var player_scene: PackedScene +@onready var spawn_points: Node3D = $SpawnPoints +@onready var players: Node3D = $Players + +func _ready() -> void: + for i: int in Game.instance.players.size(): + var player_data: Statics.PlayerData = Game.players[i] + var player_inst = player_scene.instantiate() + player_inst.name = str(player_data.id) + players.add_child(player_inst) + player_inst.setup(player_data) + player_inst.global_position = spawn_points.get_child(i).global_position + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta: float) -> void: + pass diff --git a/scene/level_test.gd.uid b/scene/level_test.gd.uid new file mode 100644 index 00000000..de77bd81 --- /dev/null +++ b/scene/level_test.gd.uid @@ -0,0 +1 @@ +uid://bdlvueh6n00lr