Trying to make sync work

This commit is contained in:
Nikolai Rodionov
2025-02-06 13:42:14 +01:00
committed by Nikolai Rodionov
parent 8f61ab6c6b
commit cc709975ba
80 changed files with 8991 additions and 260 deletions

View File

@ -0,0 +1,12 @@
extends Node3D
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass # Replace with function body.
@export var follow_speed: float = 5.0
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
var target_position = global_transform.origin # Camera's world position
global_transform.origin = lerp(global_transform.origin, target_position, follow_speed * delta)

View File

@ -0,0 +1,5 @@
extends Control
class_name Hud
@onready var camera: Camera3D = $SubViewportContainer/SubViewport/Camera3D
@onready var gun_mount: Node3D = $SubViewportContainer/SubViewport/Camera3D/GunMounta

View File

@ -0,0 +1,152 @@
[gd_scene load_steps=12 format=3 uid="uid://btlkodvngm634"]
[ext_resource type="Script" path="res://scenes/player/hud.gd" id="1_1ffy2"]
[ext_resource type="Texture2D" uid="uid://oopj5mj1vdp0" path="res://assets/crosshairs/crosshair_default.png" id="1_u13st"]
[ext_resource type="Script" path="res://scenes/player/gun_mount.gd" id="3_qmcsd"]
[sub_resource type="LabelSettings" id="LabelSettings_3bk8i"]
font_size = 70
[sub_resource type="LabelSettings" id="LabelSettings_adbcb"]
font_size = 100
font_color = Color(0.756874, 0, 0.223924, 1)
[sub_resource type="Environment" id="Environment_i2xeo"]
sdfgi_enabled = true
glow_enabled = true
[sub_resource type="Animation" id="Animation_falg4"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0.125),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector3(0, 0, 0)]
}
[sub_resource type="Animation" id="Animation_fhivu"]
resource_name = "idle"
[sub_resource type="Animation" id="Animation_mkk0p"]
resource_name = "move"
length = 0.5
loop_mode = 2
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.125, 0.25, 0.375, 0.5),
"transitions": PackedFloat32Array(1, 2, 1, 2, 1),
"update": 0,
"values": [Vector3(0, 0, 0), Vector3(-0.1, 0.1, -0.1), Vector3(0, 0, 0), Vector3(-0.1, 0.1, -0.1), Vector3(0, 0, 0)]
}
[sub_resource type="Animation" id="Animation_ah507"]
resource_name = "shooting"
length = 0.2
loop_mode = 1
step = 0.1
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.1, 0.2),
"transitions": PackedFloat32Array(1, 0.233258, 8.57419),
"update": 0,
"values": [Vector3(0, 0, 0), Vector3(0, -0.01, -0.01), Vector3(0, 0, 0)]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_u1b6p"]
_data = {
"RESET": SubResource("Animation_falg4"),
"idle": SubResource("Animation_fhivu"),
"move": SubResource("Animation_mkk0p"),
"shooting": SubResource("Animation_ah507")
}
[node name="HUD" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
script = ExtResource("1_1ffy2")
[node name="TextureRect" type="TextureRect" parent="."]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -36.0
offset_top = -36.0
offset_right = 36.0
offset_bottom = 36.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("1_u13st")
[node name="HealthIndicator" type="Label" parent="."]
layout_mode = 1
anchors_preset = 2
anchor_top = 1.0
anchor_bottom = 1.0
offset_top = -23.0
offset_right = 40.0
grow_vertical = 0
text = "100"
label_settings = SubResource("LabelSettings_3bk8i")
[node name="FPS" type="Label" parent="." groups=["player_placeholder"]]
layout_mode = 1
offset_right = 40.0
offset_bottom = 23.0
text = "0"
label_settings = SubResource("LabelSettings_adbcb")
[node name="SubViewportContainer" type="SubViewportContainer" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
stretch = true
[node name="SubViewport" type="SubViewport" parent="SubViewportContainer"]
transparent_bg = true
handle_input_locally = false
msaa_2d = 1
msaa_3d = 1
canvas_cull_mask = 4294443008
size = Vector2i(1152, 648)
render_target_update_mode = 4
[node name="Camera3D" type="Camera3D" parent="SubViewportContainer/SubViewport"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.30409, -0.371306)
cull_mask = 524288
environment = SubResource("Environment_i2xeo")
fov = 50.0
[node name="GunMount" type="Node3D" parent="SubViewportContainer/SubViewport/Camera3D"]
script = ExtResource("3_qmcsd")
[node name="AnimationPlayer" type="AnimationPlayer" parent="SubViewportContainer/SubViewport/Camera3D/GunMount"]
libraries = {
"": SubResource("AnimationLibrary_u1b6p")
}

View File

@ -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)

View File

@ -1,6 +1,6 @@
[gd_scene load_steps=5 format=3 uid="uid://3m22sdln5238"]
[gd_scene load_steps=5 format=3 uid="uid://bm80m5x5me4mp"]
[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"]

View File

@ -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)

View File

@ -1,72 +0,0 @@
# ---------------------------------------------------------------------
# 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
class_name PlayerInputController
var jumping: bool = false
var shooting: bool = false
var moving: bool = false
var look_dir: 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
@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
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
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)
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
func jump():
jumping = true
controlled_node.jump.rpc_id(1)
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 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)
#controlled_node.sync_velocity.rpc_id(1, velocity.x, velocity.y, velocity.z)
func _process(delta: float) -> void:
move_and_slide()

View File

@ -0,0 +1,135 @@
# ---------------------------------------------------------------------
# This script is supposed to control the node that is rendered on the
# client side, and send the changes to the server node
# ---------------------------------------------------------------------
extends Node3D
class_name PlayerNode
var jumping: bool = false
var shooting: bool = false
var moving: bool = false
var look_dir: Vector2
var input_direction: Vector2
var camera_sens: float = 0.002
const JUMP_VELOCITY = 4.5
var character_speed: int = 5
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
var hud: Hud
var hud_camera: Camera3D
var gun_mount: Node3D
const DEFAULT_WEAPON := "ak"
var first_slot_weapon: WeaponController
func _ready() -> void:
set_multiplayer_authority(multiplayer.get_unique_id())
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()
var hud_scene: PackedScene = ResourceLoader.load("res://scenes/player/hud.tscn")
hud = hud_scene.instantiate()
camera.add_child(hud)
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)
# Load the default weapon and set the current attack properties
func _load_weapon() -> void:
var path_tmpl := "res://scenes/weapon/guns/%s/with_hands.tscn"
var path := path_tmpl % DEFAULT_WEAPON
var scene: PackedScene = ResourceLoader.load(path)
var node: WeaponController = scene.instantiate()
first_slot_weapon = node
for child in node.find_children("*"):
if child is MeshInstance3D:
child.set_layer_mask_value(1, false)
#first_slot_weapon.position = Vector3(-1, -1, -1)
hud.find_child("GunMount").add_child(first_slot_weapon)
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():
if Input.is_action_just_pressed("jump"): jump()
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)
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
func jump():
jumping = true
controlled_node.jump.rpc_id(1)
func _physics_process(delta: float) -> void:
if multiplayer.get_unique_id() == get_multiplayer_authority():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
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
if shooting:
controlled_node.shoot.rpc_id(1)
first_slot_weapon.shoot()
var direction := (shared_node.transform.basis * Vector3(input_direction.x, 0, input_direction.y)).normalized()
if shared_node.is_on_floor():
if direction:
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)
hud_camera.global_position = global_position
func _process(delta: float) -> void:
shared_node.move_and_slide()
# -- This rpc should be called by the server in order to
# -- make the client send its position to the server
@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)
@rpc("authority", "call_local")
func adjust_position(x: float, y: float, z: float):
var new_position: Vector3 = Vector3(x, y, z)
shared_node.global_position = new_position
@rpc("any_peer", "call_local", "reliable")
func verify_rotation() -> void:
var desired_rotation: Vector3 = shared_node.global_rotation
controlled_node.send_rotation.rpc_id(1, desired_rotation.x, desired_rotation.y, desired_rotation.z)
@rpc("authority", "call_local")
func adjust_rotation(x: float, y: float, z: float):
var new_rotation: Vector3 = Vector3(x, y, z)
shared_node.rotation = new_rotation

View File

@ -0,0 +1,9 @@
[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")]

View File

@ -0,0 +1,143 @@
extends Node3D
class_name ServerNode
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
@onready var shared_node: CharacterBody3D = $SharedNode
@onready var bullet_starting_point: Node3D = $SharedNode/CameraMount/BulletStartingPoint
@onready var map_controller: MapController
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)
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:
var path_tmpl := "res://scenes/weapon/guns/%s/with_hands.tscn"
var path := path_tmpl % DEFAULT_WEAPON
var scene: PackedScene = ResourceLoader.load(path)
var node: WeaponController = scene.instantiate()
first_slot_weapon = node
first_slot_weapon.make_invisible()
first_slot_weapon.set_map_controller(map_controller)
add_child(first_slot_weapon)
func bind_player_node() -> void:
if multiplayer.get_unique_id() == owner_id:
player_node = get_tree().get_root().find_child("PlayerController", true, false)
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
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("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)
@rpc("any_peer", "call_local", "unreliable")
func jump():
jumping = true
@rpc("any_peer", "call_local", "unreliable")
func sync_velocity(x: float, y: float, z: float) -> void:
if not multiplayer.is_server():
shared_node.velocity = Vector3(x, y ,z)
@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
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")
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)
@rpc("any_peer", "call_local", "reliable")
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):
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):
if multiplayer.is_server():
var desired_rotation: Vector3 = Vector3(x, y, z)
if multiplayer.is_server():
var real_rotation: Vector3 = shared_node.rotation
var difference: Vector3 = desired_rotation - real_rotation
if is_vector_a_lower_than_b(difference, Vector3(0.3, 0.3, 0.3)):
shared_node.rotation = desired_rotation
else:
var new_rotation: Vector3 = desired_rotation.lerp(real_rotation, 0.5)
_adjust_rotation.rpc_id(owner_id, new_rotation.x, new_rotation.y, new_rotation.z)
@rpc("any_peer", "call_local", "unreliable_ordered")
func shoot():
first_slot_weapon.attack(bullet_starting_point)
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

@ -1,12 +1,33 @@
[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:rotation")
properties/0/spawn = true
properties/0/replication_mode = 1
properties/1/path = NodePath(".:owner_id")
properties/1/spawn = true
properties/1/replication_mode = 2
properties/2/path = NodePath(".:input_direction")
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="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="MainSynchronizer" type="MultiplayerSynchronizer" parent="."]
replication_config = SubResource("SceneReplicationConfig_2dhi2")
visibility_update_mode = 1
[node name="ReconciliationTimer" type="Timer" parent="."]
wait_time = 0.1
autostart = true
[connection signal="timeout" from="ReconciliationTimer" to="." method="_on_reconciliation_timer_timeout"]

View File

@ -0,0 +1,21 @@
[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, -0.127098)
[node name="Camera3D" type="Camera3D" parent="CameraMount"]
cull_mask = 524285
[node name="BulletStartingPoint" type="Node3D" parent="CameraMount"]
transform = Transform3D(-1, 0, 8.74228e-08, 0, 1, 0, -8.74228e-08, 0, -1, 0, 0, 0)