The AI made this
This commit is contained in:
parent
dc635482c8
commit
2b5935feae
@ -1,6 +1,5 @@
|
|||||||
class_name Ship
|
|
||||||
|
|
||||||
extends RigidBody3D
|
extends RigidBody3D
|
||||||
|
class_name Ship
|
||||||
|
|
||||||
@export var player_detection_area: Area3D
|
@export var player_detection_area: Area3D
|
||||||
@export var helm_location_marker: Marker3D
|
@export var helm_location_marker: Marker3D
|
||||||
@ -26,6 +25,12 @@ var old_global_position_cache: Vector3
|
|||||||
@export var move_speed: float = 1.0
|
@export var move_speed: float = 1.0
|
||||||
@export var acceleration: float = 0.1
|
@export var acceleration: float = 0.1
|
||||||
|
|
||||||
|
# Network Synchronization Variables
|
||||||
|
var last_sync_time: float = 0.0
|
||||||
|
var sync_interval: float = 0.1 # Sync every 0.1 seconds
|
||||||
|
|
||||||
|
var predicted_position: Vector3
|
||||||
|
var predicted_rotation: Quaternion
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
network_uuid = NetworkManager.register_node(self)
|
network_uuid = NetworkManager.register_node(self)
|
||||||
@ -40,14 +45,43 @@ func _ready():
|
|||||||
ship_id = randi_range(1000, 9999) #assign a random id to the ship as a unique identifier
|
ship_id = randi_range(1000, 9999) #assign a random id to the ship as a unique identifier
|
||||||
GameConsole.log_debug("Ship ID: " + str(ship_id))
|
GameConsole.log_debug("Ship ID: " + str(ship_id))
|
||||||
|
|
||||||
|
# Initialize predicted values
|
||||||
|
predicted_position = global_position
|
||||||
|
predicted_rotation = Quaternion.from_euler(global_rotation)
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
func _process(delta: float) -> void:
|
||||||
delta_time = delta
|
delta_time = delta
|
||||||
|
|
||||||
|
|
||||||
func _physics_process(_delta) -> void:
|
func _physics_process(_delta) -> void:
|
||||||
if piloting_player != null and !piloting_player.is_network_authority: return
|
# Predict movement only for non-authority clients
|
||||||
if ship_is_piloted:
|
if not piloting_player or piloting_player.is_network_authority:
|
||||||
|
_predict_movement(_delta)
|
||||||
|
else:
|
||||||
|
# Apply predicted values until server correction arrives
|
||||||
|
global_position = predicted_position
|
||||||
|
global_rotation = predicted_rotation.get_euler()
|
||||||
|
|
||||||
|
# Apply actual input if it's the authority client
|
||||||
|
if piloting_player != null and piloting_player.is_network_authority:
|
||||||
|
_apply_local_input(_delta)
|
||||||
|
|
||||||
|
# Self level slowly if host
|
||||||
|
global_rotation.x = lerpf(global_rotation.x, 0, 0.1)
|
||||||
|
global_rotation.z = lerpf(global_rotation.z, 0, 0.1)
|
||||||
|
|
||||||
|
_send_ship_sync()
|
||||||
|
|
||||||
|
func _predict_movement(_delta):
|
||||||
|
# Simple linear prediction
|
||||||
|
var predicted_velocity = linear_velocity
|
||||||
|
predicted_position += predicted_velocity * _delta
|
||||||
|
# Basic rotation prediction (can be improved)
|
||||||
|
var predicted_angular_velocity = angular_velocity
|
||||||
|
var predicted_rotation_delta = Quaternion()
|
||||||
|
predicted_rotation_delta.set_axis_angle(predicted_angular_velocity, _delta)
|
||||||
|
predicted_rotation = predicted_rotation * predicted_rotation_delta
|
||||||
|
|
||||||
|
func _apply_local_input(_delta):
|
||||||
var turn_speed = base_turn_speed / max(mass, 1)
|
var turn_speed = base_turn_speed / max(mass, 1)
|
||||||
var lift_speed = base_lift_speed / max(mass, 1)
|
var lift_speed = base_lift_speed / max(mass, 1)
|
||||||
|
|
||||||
@ -75,14 +109,6 @@ func _physics_process(_delta) -> void:
|
|||||||
|
|
||||||
angular_velocity.y = clamp(angular_velocity.y, -max_turn_speed, max_turn_speed)
|
angular_velocity.y = clamp(angular_velocity.y, -max_turn_speed, max_turn_speed)
|
||||||
|
|
||||||
# Self level slowly if host
|
|
||||||
global_rotation.x = lerpf(global_rotation.x, 0, 0.1)
|
|
||||||
global_rotation.z = lerpf(global_rotation.z, 0, 0.1)
|
|
||||||
|
|
||||||
_send_ship_sync()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func _on_area_3d_body_entered(body: Node3D) -> void:
|
func _on_area_3d_body_entered(body: Node3D) -> void:
|
||||||
if body is Player and body.get_parent() != self:
|
if body is Player and body.get_parent() != self:
|
||||||
body.ship_entered(self)
|
body.ship_entered(self)
|
||||||
@ -90,7 +116,6 @@ func _on_area_3d_body_entered(body: Node3D) -> void:
|
|||||||
body.call_deferred("reparent", self, true) #reparents player onto self (RigidBody3D)
|
body.call_deferred("reparent", self, true) #reparents player onto self (RigidBody3D)
|
||||||
print("ENTERED")
|
print("ENTERED")
|
||||||
|
|
||||||
|
|
||||||
func _on_area_3d_body_exited(body: Node3D) -> void:
|
func _on_area_3d_body_exited(body: Node3D) -> void:
|
||||||
if body is Player and body.get_parent() != get_node("/root/DevLevel/"):
|
if body is Player and body.get_parent() != get_node("/root/DevLevel/"):
|
||||||
body.ship_exited()
|
body.ship_exited()
|
||||||
@ -99,13 +124,11 @@ func _on_area_3d_body_exited(body: Node3D) -> void:
|
|||||||
body.call_deferred("reparent", get_node("/root/DevLevel/"), true) #reparents player back onto world node
|
body.call_deferred("reparent", get_node("/root/DevLevel/"), true) #reparents player back onto world node
|
||||||
print("EXITED")
|
print("EXITED")
|
||||||
|
|
||||||
|
|
||||||
func _add_ship_helm(_ship_helm_scene: PackedScene):
|
func _add_ship_helm(_ship_helm_scene: PackedScene):
|
||||||
var ship_helm_instance = _ship_helm_scene.instantiate()
|
var ship_helm_instance = _ship_helm_scene.instantiate()
|
||||||
helm_location_marker.add_child(ship_helm_instance)
|
helm_location_marker.add_child(ship_helm_instance)
|
||||||
ship_helm_instance = helm_location_marker.get_node("ShipHelm")
|
ship_helm_instance = helm_location_marker.get_node("ShipHelm")
|
||||||
|
|
||||||
|
|
||||||
func _on_property_update(uuid: String, property_name: String, value: Variant):
|
func _on_property_update(uuid: String, property_name: String, value: Variant):
|
||||||
if NetworkManager.node_map.has(uuid):
|
if NetworkManager.node_map.has(uuid):
|
||||||
var node = NetworkManager.node_map[uuid]
|
var node = NetworkManager.node_map[uuid]
|
||||||
@ -120,27 +143,33 @@ func _on_property_update(uuid: String, property_name: String, value: Variant):
|
|||||||
else:
|
else:
|
||||||
printerr("Received property update but node_id is wrong? Expected " + str(uuid) + " but got " + str(uuid))
|
printerr("Received property update but node_id is wrong? Expected " + str(uuid) + " but got " + str(uuid))
|
||||||
|
|
||||||
|
|
||||||
func _sync_piloting_state():
|
func _sync_piloting_state():
|
||||||
NetworkManager.sync_property(network_uuid, "ship_is_piloted", ship_is_piloted)
|
NetworkManager.sync_property(network_uuid, "ship_is_piloted", ship_is_piloted)
|
||||||
NetworkManager.sync_property(network_uuid, "piloting_player", piloting_player)
|
NetworkManager.sync_property(network_uuid, "piloting_player", piloting_player)
|
||||||
|
|
||||||
|
|
||||||
func _send_ship_sync():
|
func _send_ship_sync():
|
||||||
if piloting_player != null && !piloting_player.is_network_authority:
|
if Time.get_ticks_msec() - last_sync_time > sync_interval * 1000:
|
||||||
var sync_buffer: float = 2
|
last_sync_time = Time.get_ticks_msec()
|
||||||
if old_global_position_cache.distance_squared_to(global_position) > sync_buffer:
|
|
||||||
NetworkManager.sync_property(network_uuid, "global_position", global_position)
|
NetworkManager.sync_property(network_uuid, "global_position", global_position)
|
||||||
old_global_position_cache = global_position
|
|
||||||
|
|
||||||
if old_global_rotation_cache.distance_squared_to(global_rotation) > sync_buffer:
|
|
||||||
NetworkManager.sync_property(network_uuid, "global_rotation", global_rotation)
|
NetworkManager.sync_property(network_uuid, "global_rotation", global_rotation)
|
||||||
old_global_rotation_cache = global_rotation
|
NetworkManager.sync_property(network_uuid, "linear_velocity", linear_velocity)
|
||||||
|
NetworkManager.sync_property(network_uuid, "angular_velocity", angular_velocity)
|
||||||
|
|
||||||
func _handle_ship_sync_position(pos: Vector3):
|
func _handle_ship_sync_position(pos: Vector3):
|
||||||
global_position = lerp(global_position, pos, 0.1 * delta_time)
|
if piloting_player and not piloting_player.is_network_authority:
|
||||||
|
# Correct prediction with server data
|
||||||
|
predicted_position = pos
|
||||||
|
linear_velocity = (pos - global_position) / delta_time
|
||||||
|
|
||||||
func _handle_ship_sync_rotation(rot: Vector3):
|
func _handle_ship_sync_rotation(rot: Vector3):
|
||||||
global_rotation = lerp(global_rotation, rot, 0.1 * delta_time)
|
if piloting_player and not piloting_player.is_network_authority:
|
||||||
|
# Correct prediction with server data
|
||||||
|
predicted_rotation = Quaternion.from_euler(Vector3(rot.x, rot.y, rot.z))
|
||||||
|
# Calculate angular velocity based on rotation change
|
||||||
|
var received_rotation = Quaternion.from_euler(Vector3(rot.x, rot.y, rot.z))
|
||||||
|
var delta_rot = received_rotation * global_rotation.inverse()
|
||||||
|
if delta_rot.length() > 0.001:
|
||||||
|
angular_velocity = delta_rot.get_euler() / delta_time
|
||||||
|
|
||||||
|
# Apply server rotation directly
|
||||||
|
global_rotation = Quaternion.from_euler(rot).get_euler()
|
||||||
|
Loading…
Reference in New Issue
Block a user