Compare commits
2 Commits
b6bf2b4616
...
another-se
Author | SHA1 | Date | |
---|---|---|---|
349b6b7226
|
|||
cc709975ba
|
1
Makefile
1
Makefile
@ -1,6 +1,7 @@
|
||||
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))
|
||||
|
@ -78,3 +78,4 @@ jump={
|
||||
3d/physics_engine="JoltPhysics3D"
|
||||
3d/default_gravity=15.0
|
||||
2d/default_gravity=1200.0
|
||||
common/physics_interpolation=true
|
||||
|
@ -1,22 +1,68 @@
|
||||
extends Node
|
||||
extends Marker3D
|
||||
class_name CharacterWrapper
|
||||
|
||||
@export var die_script: GDScript = null
|
||||
var owner_placeholder: Node3D = 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)
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
# 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_multiplayer_authority(multiplayer.get_unique_id())
|
||||
global_position = owner_placeholder.global_position
|
||||
|
||||
# Set the owner placeholder, so the characters can send the requests to a node
|
||||
# it depends on
|
||||
func set_owner_placeholder(owner: Node3D):
|
||||
owner_placeholder = owner
|
||||
func set_owner_placeholder(owner_placeholder: Node3D):
|
||||
owner_placeholder = owner_placeholder
|
||||
|
||||
func die():
|
||||
push_warning("TODO: Implement ragdoll kind of dying and respawn character as an object")
|
||||
@ -31,3 +77,6 @@ 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
|
||||
|
@ -2322,10 +2322,11 @@ _data = {
|
||||
"t_pose": SubResource("Animation_jk3i7")
|
||||
}
|
||||
|
||||
[node name="Character" type="Node3D"]
|
||||
[node name="Character" type="Marker3D"]
|
||||
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)
|
||||
|
@ -72,7 +72,35 @@ func _on_load_map(map_name: String) -> void:
|
||||
if scene.can_instantiate():
|
||||
var node: Node3D = scene.instantiate()
|
||||
logger.info("loading map: " + map_name)
|
||||
level_root.add_child(node)
|
||||
$LevelLoader/MultiplayerSpawner.spawn_function = _map_spawn_function
|
||||
$LevelLoader/MultiplayerSpawner.spawn(map_name)
|
||||
#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
|
||||
|
||||
|
@ -6,13 +6,4 @@
|
||||
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"]
|
||||
|
@ -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,7 +14,10 @@ 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")
|
||||
@ -27,32 +30,25 @@ 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)
|
||||
|
||||
|
||||
# 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")
|
||||
@rpc("call_local", "unreliable", "any_peer")
|
||||
func _request_spawn():
|
||||
var id: int = multiplayer.get_remote_sender_id()
|
||||
_spawn_player(id)
|
||||
|
||||
func _spawn_player(id: int):
|
||||
player_spawner.spawn_players(spawn_locations, id)
|
||||
var controlled_node: ServerNode = player_spawner.get_player_node(id)
|
||||
var position := controlled_node.shared_node.global_position
|
||||
_spawn_player_controller_node.rpc_id(id, position.x, position.y, position.z)
|
||||
if multiplayer.is_server():
|
||||
player_spawner.spawn_players(spawn_locations, id)
|
||||
var controlled_node: ServerNode = player_spawner.get_player_node(id)
|
||||
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", "reliable")
|
||||
@rpc("any_peer", "call_local", "unreliable")
|
||||
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)
|
||||
@ -64,10 +60,24 @@ 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
|
||||
|
@ -2,11 +2,17 @@ class_name PlayerSpawnerController
|
||||
extends Node3D
|
||||
|
||||
func _get_spawner() -> MultiplayerSpawner:
|
||||
return $MultiplayerSpawner
|
||||
return $PlayersSpawner
|
||||
|
||||
func _get_root() -> Node3D:
|
||||
return $Players
|
||||
|
||||
func _get_model_spawner() -> MultiplayerSpawner:
|
||||
return $ModelSpawner
|
||||
|
||||
func _get_model_root() -> Node3D:
|
||||
return $Models
|
||||
|
||||
# -- Spawn a player node and sync it across all peers
|
||||
func spawn_players(spawn_location: SpawnController, id: int) -> Error:
|
||||
if multiplayer.is_server():
|
||||
@ -18,9 +24,17 @@ func spawn_players(spawn_location: SpawnController, id: int) -> Error:
|
||||
char.owner_id = id
|
||||
_get_root().add_child(char)
|
||||
char.shared_node.global_position = new_position
|
||||
|
||||
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()
|
||||
|
@ -5,9 +5,11 @@
|
||||
[node name="PlayerSpawner" type="Node3D"]
|
||||
script = ExtResource("1_2hsyd")
|
||||
|
||||
[node name="MultiplayerSpawner" type="MultiplayerSpawner" parent="."]
|
||||
[node name="PlayersSpawner" type="MultiplayerSpawner" parent="."]
|
||||
_spawnable_scenes = PackedStringArray("res://scenes/player/server_node.tscn")
|
||||
spawn_path = NodePath("../Players")
|
||||
spawn_limit = 100
|
||||
|
||||
[node name="Players" type="Node3D" parent="."]
|
||||
|
||||
[node name="Models" type="Node3D" parent="."]
|
||||
|
File diff suppressed because one or more lines are too long
912
godot/scenes/maps/maps/world.tscn
Normal file
912
godot/scenes/maps/maps/world.tscn
Normal file
File diff suppressed because one or more lines are too long
@ -60,6 +60,8 @@ 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
|
||||
|
||||
|
@ -2,4 +2,4 @@ extends Control
|
||||
class_name Hud
|
||||
|
||||
@onready var camera: Camera3D = $SubViewportContainer/SubViewport/Camera3D
|
||||
@onready var gun_mount: Node3D = $SubViewportContainer/SubViewport/Camera3D/GunMounta
|
||||
@onready var gun_mount: Node3D = $SubViewportContainer/SubViewport/Camera3D/GunMount
|
||||
|
@ -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,19 +64,17 @@ 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
|
||||
|
||||
@ -119,7 +117,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.x, desired_position.y, desired_position.z)
|
||||
controlled_node.send_position.rpc_id(1, desired_position)
|
||||
|
||||
@rpc("authority", "call_local")
|
||||
func adjust_position(x: float, y: float, z: float):
|
||||
|
@ -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,6 +23,7 @@ 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:
|
||||
@ -44,24 +45,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)
|
||||
else:
|
||||
print(str(name) + str(shared_node.velocity))
|
||||
|
||||
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
|
||||
@ -87,6 +87,7 @@ 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")
|
||||
@ -94,6 +95,10 @@ 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)
|
||||
@ -103,21 +108,19 @@ 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(x: float, y: float, z: float):
|
||||
func send_position(desired_position: Vector3):
|
||||
if multiplayer.is_server():
|
||||
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)
|
||||
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):
|
||||
|
@ -1,31 +1,30 @@
|
||||
[gd_scene load_steps=5 format=3 uid="uid://clq0b7tbincut"]
|
||||
[gd_scene load_steps=4 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:position")
|
||||
properties/0/path = NodePath("SharedNode:rotation")
|
||||
properties/0/spawn = true
|
||||
properties/0/replication_mode = 1
|
||||
properties/1/path = NodePath("SharedNode:rotation")
|
||||
properties/1/path = NodePath(".:owner_id")
|
||||
properties/1/spawn = true
|
||||
properties/1/replication_mode = 1
|
||||
properties/2/path = NodePath(".:owner_id")
|
||||
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="Node3D"]
|
||||
script = ExtResource("1_bau14")
|
||||
|
||||
[node name="SharedNode" parent="." instance=ExtResource("1_ybp5y")]
|
||||
|
||||
[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
|
||||
[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
|
||||
|
15
godot/scenes/tmp_node.gd
Normal file
15
godot/scenes/tmp_node.gd
Normal file
@ -0,0 +1,15 @@
|
||||
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()
|
18
godot/scenes/tmp_node.tscn
Normal file
18
godot/scenes/tmp_node.tscn
Normal file
@ -0,0 +1,18 @@
|
||||
[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")
|
@ -19,11 +19,9 @@ 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:
|
||||
|
@ -639,6 +639,7 @@ _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
|
||||
@ -867,6 +868,7 @@ 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
|
||||
|
Reference in New Issue
Block a user