Godot Version
4.2.2 steam-audio fork
Question
First of all, I want to tell you what I expect. The ragdoll’s arms and legs can be in different positions, but as long as they are in the same position at the root.
To synchronize, I took the global positions and rotations of all the bones and sent them to the other players. It actually works, but it’s really bad.
Now you can say just take the bone at the root and send its position and rotation, but this makes the mesh bad.
Actually, my goal is to synchronize only the root bone without breaking the simulation.
@icon("res://Network/RadomeSteamSync/SyncNode/transformSyncIcon.png")
extends Node
@export_group("SETTINGS","is")
@export var is_only_lobby_owner : bool = false ## Sadece Lobby Owner Gonderecek
@export_group("NODES","object")
@export var object_player : Node ## Karakteri sec eger lobby owner yollayacaksa gerek yok
var bones : Array[PhysicalBone3D]
signal simulating(status : bool)
var packet_index_pos : int = 0
var packet_index_rot : int = 0
var last_pos : Array[Vector3]
var last_rot : Array[Vector3]
var transform_buffer : Array = [null,null]
var last_index_buffer : PackedInt32Array = [0,0]
func _ready():
get_all_bones()
func get_pos_bone() -> Array[Vector3]:
var pos : Array[Vector3]
for bone in bones:
pos.append(bone.global_position)
return pos
func get_rot_bone() -> Array[Vector3]:
var rot : Array[Vector3]
for bone in bones:
rot.append(bone.rotation)
return rot
func get_all_bones():
for i in get_parent().get_children():
if is_instance_of(i,PhysicalBone3D):
bones.append(i)
func _on_pos_timer_timeout():
if get_pos_bone() != last_pos and NetworkManager.GAME_STARTED:
var pos = get_pos_bone()
var DATA : Dictionary = {"Idx":packet_index_pos + 1,"TYPE":NetworkManager.TYPES.RAGDOLL,"value":pos,"node_path":get_path(),"property":"pos"}
P2P._send_P2P_Packet(0,0, DATA,Steam.P2P_SEND_UNRELIABLE)
packet_index_pos = packet_index_pos + 1
last_pos = pos
func _on_rot_timer_timeout():
if get_rot_bone() != last_rot and NetworkManager.GAME_STARTED:
var rot = get_rot_bone()
var DATA : Dictionary = {"Idx":packet_index_rot + 1,"TYPE":NetworkManager.TYPES.RAGDOLL,"value":rot,"node_path":get_path(),"property":"rot"}
P2P._send_P2P_Packet(0,0, DATA,Steam.P2P_SEND_UNRELIABLE)
packet_index_rot = packet_index_rot + 1
last_rot = rot
func _physics_process(delta):
if transform_buffer[0] != null and NetworkManager.GAME_STARTED:
if transform_buffer[0]["Idx"] >= last_index_buffer[0] :
set_pos_bone(transform_buffer[0]["value"])
# Rotation
if transform_buffer[1] != null and NetworkManager.GAME_STARTED:
if transform_buffer[1]["Idx"] >= last_index_buffer[1]:
set_rot_bone(transform_buffer[1]["value"])
func set_pos_bone(DATA):
for i in range(bones.size()):
var lerped_value = lerp(bones[i].global_position,DATA[i],0.35)
bones[i].global_position = lerped_value
last_index_buffer[1] = transform_buffer[1]["Idx"]
func set_rot_bone(DATA):
for i in range(bones.size()):
var lerped_value = lerp(bones[i].rotation,DATA[i],0.35)
bones[i].rotation = lerped_value
last_index_buffer[1] = transform_buffer[1]["Idx"]
func abort():
set_process(false)
$PosTimer.stop()
$RotTimer.stop()
func _on_simulating(status : bool):
if status== true:
if is_only_lobby_owner and Steam.getLobbyOwner(NetworkManager.LOBBY_ID) == NetworkManager.STEAM_ID:
$PosTimer.start()
$RotTimer.start()
elif !is_only_lobby_owner and str(NetworkManager.STEAM_ID) == object_player.name:
$PosTimer.start()
$RotTimer.start()
print("simulated")
else:
$PosTimer.stop()
$RotTimer.stop()
Also i tried with set_bone_global_pose_override() but this made it much worse.


