From 658d68ceca365890bf94c1525f5562c663c77aed Mon Sep 17 00:00:00 2001 From: copygirl Date: Fri, 25 Apr 2025 20:49:46 +0200 Subject: [PATCH] Sync collider data --- Scenes/sync_controller.gd | 13 +++++++++++++ copyMultiplayer.gd | 21 +++++++++++++++------ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/Scenes/sync_controller.gd b/Scenes/sync_controller.gd index 9ba494a..c6bb3a4 100644 --- a/Scenes/sync_controller.gd +++ b/Scenes/sync_controller.gd @@ -2,6 +2,7 @@ extends Area3D static var StreamBuffer = load("res://Mods/copyMultiplayer/Utility/stream_buffer.gd") +static var collider_scene = load("res://Core/AvatarColliders/AvatarCollider.tscn") @export var shape: CollisionShape3D @@ -14,6 +15,7 @@ var nickname: String var version: int = -1 var bone_lookup: Array[String] var blendshape_lookup: Array[NodePath] +var collider_data: Array[Dictionary] var model_name : String var model : Node @@ -54,6 +56,7 @@ func get_display_name() -> String: func update_ping_stat() -> void: if not stats: return + if not multiplayer.is_server(): return var peer := multiplayer.multiplayer_peer.get_peer(peer_id) as ENetMultiplayerPeer if not peer: return var ping := int(peer.get_statistic(ENetPacketPeer.PEER_LAST_ROUND_TRIP_TIME)) @@ -82,6 +85,7 @@ func change_model( new_version: int, new_bone_lookup: Array[String], new_blendshape_lookup: Array[NodePath], + new_collider_data: Array[Dictionary], filename: String, ) -> void: # These should be safe to update even if the model doesn't load. @@ -89,6 +93,7 @@ func change_model( version = new_version bone_lookup = new_bone_lookup blendshape_lookup = new_blendshape_lookup + collider_data = new_collider_data if not filename.is_valid_filename(): module.print_log("ERROR: '%s' is not a valid file name!" % filename) @@ -108,6 +113,7 @@ func change_model( anim_root = anim_player.get_node(anim_player.root_node) recalculate_collision_shape() + update_colliders() module.print_log("%s switched to '%s'" % [ get_display_name(), filename ]) @@ -224,6 +230,13 @@ func recalculate_collision_shape() -> void: capsule.radius = shoulder_x * 1.75 shape.shape = capsule +func update_colliders() -> void: + if not skeleton: return + for data in collider_data: + var collider = collider_scene.instantiate() + collider.set_settings(data) + skeleton.add_child(collider) + func update_collision_shape_position() -> void: if not skeleton: return var head := _get_bone_position("Head") diff --git a/copyMultiplayer.gd b/copyMultiplayer.gd index a20c7a5..aac64a1 100644 --- a/copyMultiplayer.gd +++ b/copyMultiplayer.gd @@ -17,9 +17,10 @@ var ping_update_timer: Timer ## Hardcoded list of bone names that will get syncronized. var tracked_bones: Array[String] -var version: int = -1 -var bone_lookup: Array[String] = [] -var blendshape_lookup: Array[NodePath] = [] +var version : int = -1 +var bone_lookup : Array[String] = [] +var blendshape_lookup : Array[NodePath] = [] +var collider_data : Array[Dictionary] = [] # TODO: Remember the position of each remote player by name. ## Whether the position of remote players can be ajusted @@ -175,7 +176,7 @@ func on_peer_connected(id: int) -> void: # (Technically this doesn't need to be relayed through the server, but oh well.) if nickname: change_nickname.rpc_id(id, nickname) var filename = main_controller._last_loaded_vrm.get_file() - if filename.is_valid_filename(): change_model.rpc_id(id, version, bone_lookup, blendshape_lookup, filename) + if filename.is_valid_filename(): change_model.rpc_id(id, version, bone_lookup, blendshape_lookup, collider_data, filename) update_status() print_log("%s connected" % controller.get_display_name()) @@ -199,6 +200,8 @@ func on_connection_failed() -> void: update_enabled_state(false) func on_server_disconnected() -> void: + # NOTE: For some reason this is also called when the server is closed? + if multiplayer.is_server(): return set_status("") print_log("Disconnected from server") update_enabled_state(false) @@ -264,9 +267,14 @@ func scene_init() -> void: blendshape_lookup.append(anim.track_get_path(track_index)) continue + collider_data = [] + for collider in skeleton.get_children(): + if collider is AvatarCollider: + collider_data.append(collider.get_settings()) + if multiplayer.get_peers().size() > 1: var filename = main_controller._last_loaded_vrm.get_file() - change_model.rpc(version, bone_lookup, blendshape_lookup, filename) + change_model.rpc(version, bone_lookup, blendshape_lookup, collider_data, filename) func get_sync_controller(peer_id: int): #-> SyncController: @@ -314,11 +322,12 @@ func change_model( new_version: int, new_bone_lookup: Array[String], new_blendshape_lookup: Array[NodePath], + new_collider_data: Array[Dictionary], filename: String, ) -> void: var peer_id := multiplayer.get_remote_sender_id() var controller = get_sync_controller(peer_id) - if controller: controller.change_model(new_version, new_bone_lookup, new_blendshape_lookup, filename) + if controller: controller.change_model(new_version, new_bone_lookup, new_blendshape_lookup, new_collider_data, filename) @rpc("any_peer", "unreliable_ordered") func sync_model_animation(