add client prediction
This commit is contained in:
+1
-1
@@ -13,7 +13,7 @@ config_version=5
|
|||||||
config/name="Instructions Clear"
|
config/name="Instructions Clear"
|
||||||
run/main_scene="res://scenes/empty.tscn"
|
run/main_scene="res://scenes/empty.tscn"
|
||||||
config/features=PackedStringArray("4.3", "Mobile")
|
config/features=PackedStringArray("4.3", "Mobile")
|
||||||
run/max_fps=240
|
run/max_fps=120
|
||||||
boot_splash/show_image=false
|
boot_splash/show_image=false
|
||||||
config/icon="res://icon.svg"
|
config/icon="res://icon.svg"
|
||||||
run/size/borderless=false
|
run/size/borderless=false
|
||||||
|
|||||||
@@ -143,14 +143,12 @@ mesh = SubResource("BoxMesh_lm401")
|
|||||||
|
|
||||||
[node name="FirstFloorLight" type="OmniLight3D" parent="Lights"]
|
[node name="FirstFloorLight" type="OmniLight3D" parent="Lights"]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 4, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 4, 0)
|
||||||
light_energy = 6.0
|
|
||||||
shadow_enabled = true
|
shadow_enabled = true
|
||||||
omni_range = 40.0
|
omni_range = 40.0
|
||||||
omni_attenuation = 1.5
|
omni_attenuation = 1.5
|
||||||
|
|
||||||
[node name="SecondFloorLight" type="OmniLight3D" parent="Lights"]
|
[node name="SecondFloorLight" type="OmniLight3D" parent="Lights"]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 9, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 9, 0)
|
||||||
light_energy = 6.0
|
|
||||||
shadow_enabled = true
|
shadow_enabled = true
|
||||||
omni_range = 40.0
|
omni_range = 40.0
|
||||||
omni_attenuation = 1.5
|
omni_attenuation = 1.5
|
||||||
|
|||||||
@@ -116,3 +116,5 @@ script = ExtResource("7_jfat4")
|
|||||||
[node name="Walk" type="Node" parent="StateMachine"]
|
[node name="Walk" type="Node" parent="StateMachine"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
script = ExtResource("8_phh70")
|
script = ExtResource("8_phh70")
|
||||||
|
|
||||||
|
[connection signal="delta_synchronized" from="Sync" to="." method="_on_sync_delta_synchronized"]
|
||||||
|
|||||||
+20
-5
@@ -19,10 +19,16 @@ extends CharacterBody3D
|
|||||||
@export var air_deceleration := 5.0
|
@export var air_deceleration := 5.0
|
||||||
@export var rotation_speed := 20.0
|
@export var rotation_speed := 20.0
|
||||||
|
|
||||||
@export_group("Client Tweening")
|
@export_group("Client Smoothing")
|
||||||
@export var client_smoothing := false
|
@export var client_smoothing := false
|
||||||
@export var client_smoothing_speed := 10.0
|
@export var client_smoothing_speed := 10.0
|
||||||
@export var client_smoothing_rotation_speed := 25.0
|
@export var client_smoothing_rotation_speed := 25.0
|
||||||
|
@export var client_prediction := false
|
||||||
|
@export var client_prediction_tolerance := 0.3
|
||||||
|
|
||||||
|
@export_group("Server variables")
|
||||||
|
@export var server_position := Vector3.ZERO
|
||||||
|
@export var server_rotation := Vector3.ZERO
|
||||||
|
|
||||||
@onready var _camera_pivot: Node3D = %CameraPivot
|
@onready var _camera_pivot: Node3D = %CameraPivot
|
||||||
@onready var _camera_platform: Node3D = %CameraPlatform
|
@onready var _camera_platform: Node3D = %CameraPlatform
|
||||||
@@ -32,9 +38,8 @@ extends CharacterBody3D
|
|||||||
var camera_input_direction := Vector2.ZERO
|
var camera_input_direction := Vector2.ZERO
|
||||||
var last_direction := Vector3.FORWARD
|
var last_direction := Vector3.FORWARD
|
||||||
|
|
||||||
@export_group("Server variables")
|
var predicted_position := Vector3.ZERO
|
||||||
@export var server_position := Vector3.ZERO
|
var predicted_rotation := Vector3.ZERO
|
||||||
@export var server_rotation := Vector3.ZERO
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
state_machine.set_subject(self)
|
state_machine.set_subject(self)
|
||||||
@@ -80,6 +85,11 @@ func _physics_process(delta: float) -> void:
|
|||||||
camera_input_direction = Vector2.ZERO
|
camera_input_direction = Vector2.ZERO
|
||||||
|
|
||||||
if not multiplayer.is_server():
|
if not multiplayer.is_server():
|
||||||
|
if multiplayer.get_unique_id() == player_id and client_prediction:
|
||||||
|
predicted_position = position
|
||||||
|
predicted_rotation = skin.global_rotation
|
||||||
|
|
||||||
|
if multiplayer.get_unique_id() != player_id or not client_prediction:
|
||||||
if client_smoothing:
|
if client_smoothing:
|
||||||
position = lerp(position, server_position, client_smoothing_speed * delta)
|
position = lerp(position, server_position, client_smoothing_speed * delta)
|
||||||
skin.global_rotation.y = lerp_angle(skin.global_rotation.y, server_rotation.y, client_smoothing_rotation_speed * delta)
|
skin.global_rotation.y = lerp_angle(skin.global_rotation.y, server_rotation.y, client_smoothing_rotation_speed * delta)
|
||||||
@@ -90,4 +100,9 @@ func _physics_process(delta: float) -> void:
|
|||||||
if multiplayer.is_server():
|
if multiplayer.is_server():
|
||||||
server_position = position
|
server_position = position
|
||||||
server_rotation = skin.global_rotation
|
server_rotation = skin.global_rotation
|
||||||
#print("Velocity: %s" % velocity)
|
pass
|
||||||
|
|
||||||
|
func _on_sync_delta_synchronized() -> void:
|
||||||
|
if client_prediction and server_position.distance_to(predicted_position) > client_prediction_tolerance:
|
||||||
|
print("%v VS %v" % [server_position, predicted_position])
|
||||||
|
position = server_position
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
extends State
|
extends State
|
||||||
|
|
||||||
func process_physics(delta: float) -> State:
|
func process_physics(delta: float) -> State:
|
||||||
if not multiplayer.is_server():
|
if not multiplayer.is_server() and (multiplayer.get_unique_id() != subject.player_id or not subject.client_prediction):
|
||||||
return
|
return
|
||||||
|
|
||||||
var target_velocity = Vector3(0, subject.velocity.y, 0)
|
var target_velocity = Vector3(0, subject.velocity.y, 0)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
extends State
|
extends State
|
||||||
|
|
||||||
func process_physics(delta: float) -> State:
|
func process_physics(delta: float) -> State:
|
||||||
if not multiplayer.is_server():
|
if not multiplayer.is_server() and (multiplayer.get_unique_id() != subject.player_id or not subject.client_prediction):
|
||||||
return
|
return
|
||||||
|
|
||||||
var target_velocity = Vector3(0, subject.velocity.y, 0)
|
var target_velocity = Vector3(0, subject.velocity.y, 0)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
extends State
|
extends State
|
||||||
|
|
||||||
func process_physics(delta: float) -> State:
|
func process_physics(delta: float) -> State:
|
||||||
if not multiplayer.is_server():
|
if not multiplayer.is_server() and (multiplayer.get_unique_id() != subject.player_id or not subject.client_prediction):
|
||||||
return
|
return
|
||||||
|
|
||||||
var input_direction = %Input.direction
|
var input_direction = %Input.direction
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ func _change_state(new_state: State) -> void:
|
|||||||
current_state.exit()
|
current_state.exit()
|
||||||
|
|
||||||
current_state = new_state
|
current_state = new_state
|
||||||
print("Entering: %s" % current_state.name)
|
#print("Entering: %s" % current_state.name)
|
||||||
current_state.enter()
|
current_state.enter()
|
||||||
|
|
||||||
func process_physics(delta: float) -> void:
|
func process_physics(delta: float) -> void:
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
extends State
|
extends State
|
||||||
|
|
||||||
func process_physics(delta: float) -> State:
|
func process_physics(delta: float) -> State:
|
||||||
if not multiplayer.is_server():
|
if not multiplayer.is_server() and (multiplayer.get_unique_id() != subject.player_id or not subject.client_prediction):
|
||||||
return
|
return
|
||||||
|
|
||||||
var input_direction = %Input.direction
|
var input_direction = %Input.direction
|
||||||
|
|||||||
Reference in New Issue
Block a user