6 Commits

Author SHA1 Message Date
dee082c7e4 WIP: Some updates 2025-02-08 19:05:28 +01:00
084d8248c7 WIP: Some updates 2025-02-08 19:04:20 +01:00
b6bf2b4616 WIP: Some updates 2025-02-08 17:11:19 +01:00
5ab840cdd8 WIP: Some updates 2025-02-08 17:04:17 +01:00
89992b1ef4 Fix the sync and add shooting 2025-02-06 22:06:54 +01:00
ad95c99149 Trying to make sync work 2025-02-06 13:42:14 +01:00
19 changed files with 1038 additions and 1130 deletions

View File

@ -1,7 +1,6 @@
JOLT_VERSION = v0.14.0-stable
JOLT_URL = https://github.com/godot-jolt/godot-jolt/releases/download/${JOLT_VERSION}/godot-jolt_${JOLT_VERSION}.zip
JOLT_DIR = ./godot/jolt
install_jolt:
rm -rf ${JOLT_DIR}
$(eval DOWNLOAD := $(shell mktemp -d))

View File

@ -1,68 +1,22 @@
extends Marker3D
extends Node
class_name CharacterWrapper
@export var die_script: GDScript = null
@export var owner_placeholder: CharacterBody3D = null
@export var server_node: Node3D # The real synced node from the server
@export var interpolation_delay: float = 0.1 # Stay 100ms behind for smooth interpolation
@export var snap_threshold: float = 2.0 # If desync is larger than this, snap instantly
var position_buffer = [] # Stores past positions (tuples of (timestamp, position, rotation))
var previous_position: Vector3 = Vector3.ZERO
var previous_rotation: Quaternion = Quaternion.IDENTITY
var pseudo_velocity: Vector3 = Vector3.ZERO # Approximate velocity without CharacterBody3D
func _physics_process(delta: float) -> void:
var server_pos = owner_placeholder.global_transform.origin
var server_rot = owner_placeholder.global_transform.basis.get_rotation_quaternion()
# Calculate pseudo velocity (difference per second)
pseudo_velocity = (server_pos - previous_position) / delta
previous_position = server_pos # Store for next frame
previous_rotation = server_rot # Store rotation for next frame
# Store position & rotation in buffer
position_buffer.append([Time.get_ticks_msec() / 1000.0, server_pos, server_rot])
# Remove old positions to keep buffer clean
while position_buffer.size() > 2 and position_buffer[1][0] < (Time.get_ticks_msec() / 1000.0) - interpolation_delay:
position_buffer.pop_front()
# Get current client position
var client_pos = global_transform.origin
# Check if the client is too far from the server
if client_pos.distance_to(server_pos) > snap_threshold:
global_transform.origin = server_pos # Instantly move to the correct position
global_transform.basis = Basis(server_rot) # Instantly rotate to the correct orientation
position_buffer.clear() # Reset buffer to prevent interpolation from old positions
return # Skip interpolation this frame to avoid weird blending
# If we have at least 2 points, interpolate between them
if position_buffer.size() >= 2:
var t_now = (Time.get_ticks_msec() / 1000.0) - interpolation_delay
var prev_point = position_buffer[0]
var next_point = position_buffer[1]
var alpha = (t_now - prev_point[0]) / (next_point[0] - prev_point[0])
alpha = clamp(alpha, 0.0, 1.0)
# Interpolate position
global_transform.origin = prev_point[1].lerp(next_point[1], alpha)
# Interpolate rotation using slerp
var interpolated_rot = prev_point[2].slerp(next_point[2], alpha)
global_transform.basis = Basis(interpolated_rot)
var owner_placeholder: Node3D = null
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
set_multiplayer_authority(multiplayer.get_unique_id())
global_position = owner_placeholder.global_position
# Characters should be always controlled by the server and synced accross client
# The owner should be responsible for the syncronization, since this node is
# just a dummy that is following the controller
set_multiplayer_authority(1)
pass # Replace with function body.
# Set the owner placeholder, so the characters can send the requests to a node
# it depends on
func set_owner_placeholder(owner_placeholder: Node3D):
owner_placeholder = owner_placeholder
func set_owner_placeholder(owner: Node3D):
owner_placeholder = owner
func die():
push_warning("TODO: Implement ragdoll kind of dying and respawn character as an object")
@ -77,6 +31,3 @@ func _on_area_body_part_hit(damage: int) -> void:
owner_placeholder.take_damage(damage)
else:
push_warning("Node doesn't know how to take the damage")
func is_vector_a_lower_than_b(vec_a: Vector3, vec_b: Vector3) -> bool:
return vec_a.x < vec_b.x and vec_a.y < vec_b.y and vec_a.z < vec_b.z

View File

@ -2322,11 +2322,10 @@ _data = {
"t_pose": SubResource("Animation_jk3i7")
}
[node name="Character" type="Marker3D"]
[node name="Character" type="Node3D"]
script = ExtResource("1_k4p2i")
[node name="Model" type="Node3D" parent="."]
transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 0, 0)
[node name="Body" type="Node3D" parent="Model"]
transform = Transform3D(0.01, 0, 0, 0, 0, -0.01, 0, 0.01, 0, 0, 0, 0)
@ -2797,7 +2796,7 @@ mesh = SubResource("ArrayMesh_7ywky")
skin = SubResource("Skin_rvj8b")
[node name="HeadAttachment" type="BoneAttachment3D" parent="Model/Body/Skeleton3D"]
transform = Transform3D(0.882565, -0.444116, -0.154401, 0.270521, 0.211033, 0.939299, -0.384574, -0.870762, 0.306393, -6.4511, 7.27767, -150.755)
transform = Transform3D(0.882565, -0.444116, -0.154401, 0.270521, 0.211033, 0.9393, -0.384574, -0.870762, 0.306393, -6.4511, 7.27766, -150.755)
bone_name = "mixamorig_Head"
bone_idx = 5
@ -2814,7 +2813,7 @@ transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0,
shape = SubResource("CapsuleShape3D_yrrmu")
[node name="TorsoAttachment" type="BoneAttachment3D" parent="Model/Body/Skeleton3D"]
transform = Transform3D(0.766679, -0.0560176, -0.639582, 0.64197, 0.0531821, 0.764883, -0.00883259, -0.997012, 0.0767353, 3.85161, -5.43985, -116.78)
transform = Transform3D(0.766679, -0.0560176, -0.639582, 0.64197, 0.053182, 0.764883, -0.0088326, -0.997012, 0.0767351, 3.85161, -5.43985, -116.78)
bone_name = "mixamorig_Spine1"
bone_idx = 2
@ -2828,7 +2827,7 @@ body_part = "Torso"
shape = SubResource("CapsuleShape3D_tr87i")
[node name="RightHipAttachment" type="BoneAttachment3D" parent="Model/Body/Skeleton3D"]
transform = Transform3D(-0.807937, -0.161163, -0.566802, -0.581917, 0.0667467, 0.810505, -0.092791, 0.984668, -0.14771, -7.363, -5.25271, -89.2051)
transform = Transform3D(-0.807937, -0.161163, -0.566801, -0.581917, 0.0667468, 0.810505, -0.092791, 0.984668, -0.147711, -7.363, -5.25271, -89.2051)
bone_name = "mixamorig_RightUpLeg"
bone_idx = 60
@ -2844,7 +2843,7 @@ transform = Transform3D(0.997222, -0.0744854, -0.000943551, 0.0744854, 0.997222,
shape = SubResource("CapsuleShape3D_xyxrh")
[node name="RightLegAttachment" type="BoneAttachment3D" parent="Model/Body/Skeleton3D"]
transform = Transform3D(-0.801839, 0.200184, -0.563011, -0.593879, -0.371127, 0.713844, -0.0660485, 0.906748, 0.416469, -13.9061, -2.54283, -49.228)
transform = Transform3D(-0.801839, 0.200184, -0.563011, -0.593879, -0.371127, 0.713844, -0.0660485, 0.906748, 0.416469, -13.9061, -2.54282, -49.228)
bone_name = "mixamorig_RightLeg"
bone_idx = 61
@ -2859,7 +2858,7 @@ body_part = "Right Leg"
shape = SubResource("CapsuleShape3D_h5mrs")
[node name="RightFootAttachment" type="BoneAttachment3D" parent="Model/Body/Skeleton3D"]
transform = Transform3D(-0.588698, -0.731611, -0.343773, -0.806695, 0.504491, 0.307786, -0.0517495, 0.458513, -0.88718, -5.4786, -18.1669, -11.0549)
transform = Transform3D(-0.588698, -0.731611, -0.343773, -0.806695, 0.504491, 0.307786, -0.0517494, 0.458513, -0.88718, -5.4786, -18.1669, -11.0549)
bone_name = "mixamorig_RightFoot"
bone_idx = 62
@ -2874,7 +2873,7 @@ body_part = "Right Foot"
shape = SubResource("BoxShape3D_1pj41")
[node name="RightArmAttachment" type="BoneAttachment3D" parent="Model/Body/Skeleton3D"]
transform = Transform3D(0.374872, -0.587376, 0.717259, 0.864165, 0.501541, -0.0409307, -0.335693, 0.635174, 0.695604, -10.8404, -16.1981, -138.841)
transform = Transform3D(0.374872, -0.587376, 0.717259, 0.864165, 0.501541, -0.0409305, -0.335693, 0.635173, 0.695604, -10.8404, -16.1981, -138.841)
bone_name = "mixamorig_RightArm"
bone_idx = 32
@ -2889,7 +2888,7 @@ body_part = "Right Arm"
shape = SubResource("CapsuleShape3D_56i6t")
[node name="RightForearmAttachment" type="BoneAttachment3D" parent="Model/Body/Skeleton3D"]
transform = Transform3D(0.525953, 0.457071, 0.717259, -0.623016, 0.781137, -0.0409307, -0.578986, -0.425336, 0.695604, -26.9373, -2.45355, -121.435)
transform = Transform3D(0.525953, 0.457071, 0.717259, -0.623016, 0.781137, -0.0409306, -0.578986, -0.425336, 0.695604, -26.9373, -2.45355, -121.435)
bone_name = "mixamorig_RightForeArm"
bone_idx = 33
@ -2904,7 +2903,7 @@ body_part = "Right Forearm"
shape = SubResource("CapsuleShape3D_1sjun")
[node name="RightPalmAttachment" type="BoneAttachment3D" parent="Model/Body/Skeleton3D"]
transform = Transform3D(-0.101872, 0.0272958, 0.994423, -0.100369, 0.994241, -0.0375728, -0.989721, -0.103637, -0.0985454, -14.3155, 19.1172, -133.18)
transform = Transform3D(-0.101872, 0.0272956, 0.994423, -0.100369, 0.994241, -0.0375728, -0.989721, -0.103637, -0.0985452, -14.3155, 19.1172, -133.18)
bone_name = "mixamorig_RightHand"
bone_idx = 34
@ -2920,7 +2919,7 @@ transform = Transform3D(1, -4.54747e-13, -5.68434e-14, 0, 1, 2.94416e-14, 0, -8.
shape = SubResource("SphereShape3D_eryh8")
[node name="LeftHipAttachment" type="BoneAttachment3D" parent="Model/Body/Skeleton3D"]
transform = Transform3D(-0.982279, 0.127, 0.137838, 0.176971, 0.38628, 0.905245, 0.0617221, 0.913597, -0.40191, 6.6331, 6.44913, -89.6507)
transform = Transform3D(-0.982279, 0.127, 0.137838, 0.176971, 0.38628, 0.905245, 0.061722, 0.913597, -0.40191, 6.6331, 6.44913, -89.6507)
bone_name = "mixamorig_LeftUpLeg"
bone_idx = 55
@ -2936,7 +2935,7 @@ transform = Transform3D(0.997222, -0.0744854, -0.000943551, 0.0744854, 0.997222,
shape = SubResource("CapsuleShape3D_xyxrh")
[node name="LeftLegAttachment" type="BoneAttachment3D" parent="Model/Body/Skeleton3D"]
transform = Transform3D(-0.982093, 0.0367378, 0.18478, 0.184413, -0.013171, 0.982761, 0.0385382, 0.999238, 0.00616023, 11.7892, 22.1319, -52.5592)
transform = Transform3D(-0.982093, 0.0367378, 0.18478, 0.184413, -0.0131707, 0.982761, 0.0385382, 0.999238, 0.00616005, 11.7892, 22.1319, -52.5592)
bone_name = "mixamorig_LeftLeg"
bone_idx = 56
@ -2951,7 +2950,7 @@ body_part = "Left Leg"
shape = SubResource("CapsuleShape3D_h5mrs")
[node name="LeftFootAttachment" type="BoneAttachment3D" parent="Model/Body/Skeleton3D"]
transform = Transform3D(-0.977188, 0.206477, 0.0497126, 0.205976, 0.864368, 0.45874, 0.0517493, 0.458515, -0.887179, 13.3358, 21.5774, -10.4923)
transform = Transform3D(-0.977188, 0.206477, 0.0497126, 0.205976, 0.864368, 0.45874, 0.0517493, 0.458514, -0.887179, 13.3358, 21.5774, -10.4923)
bone_name = "mixamorig_LeftFoot"
bone_idx = 57
@ -2981,7 +2980,7 @@ body_part = "Left Arm"
shape = SubResource("CapsuleShape3D_56i6t")
[node name="LeftForearmAttachment" type="BoneAttachment3D" parent="Model/Body/Skeleton3D"]
transform = Transform3D(0.0873336, -0.555, -0.827253, 0.636753, 0.669735, -0.3821, 0.766106, -0.493386, 0.411889, 11.27, 33.558, -124.364)
transform = Transform3D(0.0873334, -0.555, -0.827253, 0.636753, 0.669735, -0.3821, 0.766106, -0.493386, 0.411888, 11.27, 33.558, -124.364)
bone_name = "mixamorig_LeftForeArm"
bone_idx = 9
@ -2996,7 +2995,7 @@ body_part = "Left Forearm"
shape = SubResource("CapsuleShape3D_1sjun")
[node name="LeftPalmAttachment" type="BoneAttachment3D" parent="Model/Body/Skeleton3D"]
transform = Transform3D(-0.752812, -0.657604, -0.028832, -0.658199, 0.751584, 0.0435493, -0.00696856, 0.0517617, -0.998635, -4.05605, 52.0524, -137.988)
transform = Transform3D(-0.752812, -0.657604, -0.0288319, -0.658199, 0.751583, 0.0435492, -0.00696859, 0.0517616, -0.998635, -4.05606, 52.0524, -137.988)
bone_name = "mixamorig_LeftHand"
bone_idx = 10

View File

@ -72,35 +72,7 @@ func _on_load_map(map_name: String) -> void:
if scene.can_instantiate():
var node: Node3D = scene.instantiate()
logger.info("loading map: " + map_name)
$LevelLoader/MultiplayerSpawner.spawn_function = _map_spawn_function
$LevelLoader/MultiplayerSpawner.spawn(map_name)
#level_root.add_child(node)
level_root.add_child(node)
else:
logger.error("Can't initialize")
var thread: Thread
var map_node: Node
var mutex: Mutex
func _load_the_map_in_thread(map_name):
var path_tmpl := "res://scenes/maps/maps/%s"
var path := path_tmpl % map_name
if not ResourceLoader.exists(path):
logger.error("map " + map_name + " doesn't exist")
mutex.lock()
var scene: PackedScene = ResourceLoader.load(path)
if scene.can_instantiate():
map_node = scene.instantiate()
mutex.unlock()
func _map_spawn_function(map_name: Variant) -> Node:
thread = Thread.new()
mutex = Mutex.new()
thread.start(Callable(self, "_load_the_map_in_thread").bind(map_name))
await thread.wait_to_finish()
mutex.lock()
var result = map_node
mutex.unlock()
return result

View File

@ -6,4 +6,13 @@
editor_description = "This node serves a starting point for the game. When the game is running as a dedicated server it's supposed to read the config file and start the server, when the game is running in a default mode, it should render the main menu"
script = ExtResource("1_eb14f")
[node name="LevelLoader" type="Node" parent="."]
editor_description = "This node is supposed to make it possible to sync the server data across all the possible players"
[node name="Level" type="Node3D" parent="LevelLoader"]
[node name="MultiplayerSpawner" type="MultiplayerSpawner" parent="LevelLoader"]
_spawnable_scenes = PackedStringArray("res://scenes/maps/maps/lowpoly_tdm_1.tscn")
spawn_path = NodePath("../Level")
[connection signal="load_map" from="." to="." method="_on_load_map"]

View File

@ -3,7 +3,7 @@ class_name MapController
const PLAYER_SPAWNER: String = "res://scenes/maps/base/player_spawner/player_spawner.tscn"
const BULLET_SPAWNER: String = "res://scenes/maps/base/bullet_spawner/bullet_spawner.tscn"
const WORLD: String = "res://scenes/maps/maps/world.tscn"
var player_spawner: PlayerSpawnerController
var bullet_spawner: BulletSpawnerController
var client_node: Node3D
@ -14,10 +14,7 @@ var client_node: Node3D
func _ready() -> void:
# add player spawner
var err: Error = OK
err = _add_world()
if err != OK:
push_error("Couldn't load world")
return
err = _add_player_spawner()
if err != OK:
push_error("Couldn't load player spawner")
@ -30,13 +27,21 @@ func _ready() -> void:
client_node = Node3D.new()
client_node.name = "ClientNode"
add_child(client_node)
# add objects spawner
if not OS.has_feature("dedicated_server"):
_request_spawn.rpc_id(1)
@rpc("call_local", "unreliable", "any_peer")
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
if multiplayer.is_server():
pass
#var active_players = player_spawner._get_root().get_children()
#for n in active_players:
#if not Server.players.has(n.owner_id):
#_remove_player(n.owner_id)
@rpc("call_local", "reliable", "any_peer")
func _request_spawn():
var id: int = multiplayer.get_remote_sender_id()
_spawn_player(id)
@ -48,7 +53,7 @@ func _spawn_player(id: int):
var position := controlled_node.shared_node.global_position
_spawn_player_controller_node.rpc_id(id, position.x, position.y, position.z)
@rpc("any_peer", "call_local", "unreliable")
@rpc("any_peer", "call_local", "reliable")
func _spawn_player_controller_node(x: float, y: float, z: float):
var path := "res://scenes/player/player_node.tscn"
var scene: PackedScene = ResourceLoader.load(path)
@ -60,24 +65,10 @@ func _spawn_player_controller_node(x: float, y: float, z: float):
player_node.shared_node.global_position = Vector3(x,y,z)
controlled_node.bind_player_node()
func spawn_player_model(owner_node: CharacterBody3D, owner_id: int):
if multiplayer.get_unique_id() != owner_id:
player_spawner.spawn_player_model(owner_node)
func _remove_player(id: int):
player_spawner.remove_player(id)
func _add_world() -> Error :
if not ResourceLoader.exists(WORLD):
return ERR_DOES_NOT_EXIST
var scene: PackedScene = ResourceLoader.load(WORLD)
if not scene.can_instantiate():
return ERR_CANT_OPEN
var node: Node3D = scene.instantiate()
add_child(node)
return OK
func _add_player_spawner() -> Error :
if not ResourceLoader.exists(PLAYER_SPAWNER):
return ERR_DOES_NOT_EXIST

View File

@ -25,16 +25,13 @@ func spawn_players(spawn_location: SpawnController, id: int) -> Error:
_get_root().add_child(char)
char.shared_node.global_position = new_position
var model_scene: PackedScene = ResourceLoader.load("res://scenes/characters/y-bot/character.tscn")
var model: CharacterWrapper = model_scene.instantiate()
model.global_position = new_position
_get_model_root().add_child(model)
return OK
return ERR_UNAUTHORIZED
func spawn_player_model(owner_node: CharacterBody3D):
var model_scene: PackedScene = ResourceLoader.load("res://scenes/characters/y-bot/character.tscn")
var model: CharacterWrapper = model_scene.instantiate()
model.global_position = owner_node.global_position
model.owner_placeholder = owner_node
_get_model_root().add_child(model)
func remove_player(id: int) -> Error:
if multiplayer.is_server():
var found_childen: Array[Node] =_get_root().get_children()

View File

@ -6,10 +6,14 @@
script = ExtResource("1_2hsyd")
[node name="PlayersSpawner" type="MultiplayerSpawner" parent="."]
_spawnable_scenes = PackedStringArray("res://scenes/player/server_node.tscn")
_spawnable_scenes = PackedStringArray("res://scenes/player/server_node.tscn", "res://scenes/characters/y-bot/character.tscn")
spawn_path = NodePath("../Players")
spawn_limit = 100
[node name="Players" type="Node3D" parent="."]
[node name="Models" type="Node3D" parent="."]
[node name="ModelSpawner" type="MultiplayerSpawner" parent="."]
_spawnable_scenes = PackedStringArray("res://scenes/characters/y-bot/character.tscn")
spawn_path = NodePath("../Models")

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -60,8 +60,6 @@ func _on_create_pressed() -> void:
func _on_join_server_pressed() -> void:
var ip: String = $JoinServerMenu/Host/TextEdit.text
var port: int = $JoinServerMenu/Port/TextEdit.text.to_int()
GameServerAutoload.join_server(ip, port)
_get_game_root().load_map.emit(GameServerAutoload.current_map)
visible = false

View File

@ -2,4 +2,4 @@ extends Control
class_name Hud
@onready var camera: Camera3D = $SubViewportContainer/SubViewport/Camera3D
@onready var gun_mount: Node3D = $SubViewportContainer/SubViewport/Camera3D/GunMount
@onready var gun_mount: Node3D = $SubViewportContainer/SubViewport/Camera3D/GunMounta

View File

@ -39,9 +39,9 @@ func _ready() -> void:
hud_camera = hud.camera
gun_mount = hud.gun_mount
_load_weapon()
#for child in controlled_node.find_child("Model").find_children("*"):
#if child is MeshInstance3D:
#child.set_layer_mask_value(1, false)
for child in controlled_node.find_child("Model").find_children("*"):
if child is MeshInstance3D:
child.set_layer_mask_value(1, false)
# Load the default weapon and set the current attack properties
func _load_weapon() -> void:
@ -64,17 +64,19 @@ func initial_position_sync():
func _input(event):
if multiplayer.get_unique_id() == get_multiplayer_authority():
if Input.is_action_just_pressed("jump"): jump()
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
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, camera_mount.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_backward"):
moving = true
else:
moving = false
input_direction = Input.get_vector("move_left", "move_right", "move_forward", "move_backward")
controlled_node.set_input_direction.rpc_id(1, input_direction)
if Input.is_action_just_pressed("shoot"): shooting = true
if Input.is_action_just_released("shoot"): shooting = false
@ -117,7 +119,7 @@ func _process(delta: float) -> void:
@rpc("any_peer", "call_local", "reliable")
func verify_position() -> void:
var desired_position: Vector3 = shared_node.global_position
controlled_node.send_position.rpc_id(1, desired_position)
controlled_node.send_position.rpc_id(1, desired_position.x, desired_position.y, desired_position.z)
@rpc("authority", "call_local")
func adjust_position(x: float, y: float, z: float):

View File

@ -1,14 +1,14 @@
extends Node3D
class_name ServerNode
var jumping := false
var input_direction: Vector2
var player_node: PlayerNode
# TODO: Shoould not be defined here
const DEFAULT_WEAPON := "ak"
var first_slot_weapon: WeaponController
@export var jumping := false
@export var input_direction: Vector2
@export var owner_id: int = 0
@onready var camera_mount: Node3D = $SharedNode/CameraMount
@ -23,7 +23,6 @@ func _ready() -> void:
shared_node.set_collision_mask_value(3, true)
map_controller = find_parent("Map")
_load_weapon()
map_controller.spawn_player_model(shared_node, owner_id)
# Load the default weapon and set the current attack properties
func _load_weapon() -> void:
@ -45,22 +44,23 @@ func _physics_process(delta: float) -> void:
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:
$SharedNode/Character/Model/AnimationPlayer.play("riffle_run")
#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:
$SharedNode/Character/Model/AnimationPlayer.play("riffle_idle")
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()
else:
print(str(name) + str(shared_node.velocity))
@rpc("authority", "call_remote", "unreliable_ordered")
func update_position(real_position: Vector3):
if not multiplayer.is_server():
shared_node.global_transform.origin = lerp(shared_node.global_transform.origin, real_position, 1.0)
shared_node.move_and_slide()
@rpc("any_peer", "call_local", "unreliable")
func jump():
@ -87,7 +87,6 @@ func set_rotation_y(y: float):
func _on_reconciliation_timer_timeout() -> void:
if multiplayer.is_server():
_veryfy_position_and_rotation.rpc_id(owner_id)
update_position.rpc(shared_node.global_transform.origin)
$ReconciliationTimer.start()
@rpc("any_peer", "call_local", "reliable")
@ -95,10 +94,6 @@ func _veryfy_position_and_rotation() -> void:
player_node.verify_position()
player_node.verify_rotation()
#@rpc("authority", "call_remote", "unreliable")
#func _sync_transorm():
@rpc("any_peer", "call_local", "reliable")
func _adjust_position(x: float, y: float, z: float) -> void:
player_node.adjust_position(x, y, z)
@ -108,19 +103,21 @@ func _adjust_rotation(x: float, y: float, z: float) -> void:
player_node.adjust_rotation(x, y, z)
@rpc("any_peer", "call_local", "reliable")
func send_position(desired_position: Vector3):
func send_position(x: float, y: float, z: float):
if multiplayer.is_server():
var real_position: Vector3 = shared_node.global_position
var difference: Vector3 = desired_position - real_position
if is_vector_a_lower_than_b(difference, Vector3(0.2, 0.2, 0.2)):
shared_node.global_position = desired_position
elif is_vector_a_lower_than_b(difference, Vector3(0.4, 0.4, 0.4)):
var new_position: Vector3 = desired_position.lerp(real_position, 0.5)
push_warning("player position is not valid, lerping")
_adjust_position.rpc_id(owner_id, new_position.x, new_position.y, new_position.z)
else:
push_warning("player position is not valid, adjusting")
_adjust_position.rpc_id(owner_id, real_position.x, real_position.y, real_position.z)
var desired_position: Vector3 = Vector3(x, y, z)
if multiplayer.is_server():
var real_position: Vector3 = shared_node.global_position
var difference: Vector3 = desired_position - real_position
if is_vector_a_lower_than_b(difference, Vector3(0.2, 0.2, 0.2)):
shared_node.global_position = desired_position
elif is_vector_a_lower_than_b(difference, Vector3(0.4, 0.4, 0.4)):
var new_position: Vector3 = desired_position.lerp(real_position, 0.5)
push_warning("player position is not valid, lerping")
_adjust_position.rpc_id(owner_id, new_position.x, new_position.y, new_position.z)
else:
push_warning("player position is not valid, adjusting")
_adjust_position.rpc_id(owner_id, real_position.x, real_position.y, real_position.z)
@rpc("any_peer", "call_local")
func send_rotation(x: float, y: float, z: float):

View File

@ -1,30 +1,31 @@
[gd_scene load_steps=4 format=3 uid="uid://clq0b7tbincut"]
[gd_scene load_steps=5 format=3 uid="uid://clq0b7tbincut"]
[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"]
[ext_resource type="PackedScene" uid="uid://ddwrs0so7swxn" path="res://scenes/characters/y-bot/character.tscn" id="3_eykxo"]
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_2dhi2"]
properties/0/path = NodePath("SharedNode:rotation")
properties/0/path = NodePath("SharedNode:position")
properties/0/spawn = true
properties/0/replication_mode = 1
properties/1/path = NodePath(".:owner_id")
properties/1/path = NodePath("SharedNode:rotation")
properties/1/spawn = true
properties/1/replication_mode = 2
properties/2/path = NodePath(".:input_direction")
properties/1/replication_mode = 1
properties/2/path = NodePath(".:owner_id")
properties/2/spawn = true
properties/2/replication_mode = 1
properties/3/path = NodePath(".:jumping")
properties/3/spawn = true
properties/3/replication_mode = 2
[node name="ServerNode" type="Node3D"]
script = ExtResource("1_bau14")
[node name="SharedNode" parent="." instance=ExtResource("1_ybp5y")]
[node name="MainSynchronizer" type="MultiplayerSynchronizer" parent="."]
[node name="Character" parent="SharedNode" instance=ExtResource("3_eykxo")]
transform = Transform3D(-1, 0, 8.74228e-08, 0, 1, 0, -8.74228e-08, 0, -1, 0, 0, 0)
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."]
replication_interval = 0.1
replication_config = SubResource("SceneReplicationConfig_2dhi2")
visibility_update_mode = 1
[node name="ReconciliationTimer" type="Timer" parent="."]
wait_time = 0.1

View File

@ -1,15 +0,0 @@
extends CharacterBody3D
class_name TmpNode
@export var owner_placeholder: CharacterBody3D = null
func _ready() -> void:
set_multiplayer_authority(multiplayer.get_unique_id())
global_position = owner_placeholder.global_position
func _physics_process(delta: float) -> void:
# Add the gravity.
if not is_on_floor():
velocity += get_gravity() * delta
velocity = owner_placeholder.velocity
move_and_slide()

View File

@ -1,18 +0,0 @@
[gd_scene load_steps=3 format=3 uid="uid://kjeyhc8qpykm"]
[ext_resource type="Script" path="res://scenes/tmp_node.gd" id="1_vutt1"]
[sub_resource type="BoxShape3D" id="BoxShape3D_crgjo"]
size = Vector3(0.01, 0.01, 0.01)
[node name="TmpNode" type="CharacterBody3D"]
collision_layer = 0
collision_mask = 0
script = ExtResource("1_vutt1")
[node name="CSGBox3D" type="CSGBox3D" parent="."]
transform = Transform3D(32.0413, 0, 0, 0, 32.0413, 0, 0, 0, 32.0413, 0, 565.322, 0)
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.54251, 0)
shape = SubResource("BoxShape3D_crgjo")

View File

@ -19,9 +19,11 @@ var can_shoot: bool = true
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
cooldown_timer.wait_time = cooldown
print("test")
@onready var bullet_trace_distance: Node3D = $BulletTraceDistance
@onready var bullet_trail_end: Node3D = $BulletTrailEnd
@onready var gun_animation = $ShotAnimation
func shoot() -> Error:
if can_shoot:

View File

@ -639,7 +639,6 @@ _data = {
}
[node name="WithHands" type="Node3D"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.528017, -0.924033, 0)
script = ExtResource("1_h1xyo")
damage = 50
cooldown = 0.15
@ -868,7 +867,6 @@ transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 1.8676
libraries = {
"": SubResource("AnimationLibrary_g403t")
}
playback_auto_capture = false
[node name="CooldownTimer" type="Timer" parent="."]
process_callback = 0