-
-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
No physics applied to RigidBody3D when TickInterpolator also active #265
Comments
RidigBodies don't directly support being moved the same way most other nodes do. They're expected to be driven almost exclusively by the physics engine. TickInterpolator which is interpolating position between ticks is probably not the right tool to use. The closest we can probably get is to sync physic states from the authoritative server and copy and apply them to the clients This probably needs it's own dedicated Node. RigidBodySynchronizer? It won't be able to participate in rollback either since there's no current way to run more than a single physics simulation per frame in Godot. |
There's an implementation here of what a physics synchronizer can look like: Copying the code to here as things tend to disappear on the Internet over time. extends MultiplayerSynchronizer
class_name PhysicsSynchronizer
@export var sync_bstate_array : Array = \
[0, Vector3.ZERO, Quaternion.IDENTITY, Vector3.ZERO, Vector3.ZERO]
@onready var sync_object : RigidBody3D = get_node(root_path)
@onready var body_state : PhysicsDirectBodyState3D = \
PhysicsServer3D.body_get_direct_state( sync_object.get_rid() )
var frame : int = 0
var last_frame : int = 0
enum {
FRAME,
ORIGIN,
QUAT, # the quaternion is used for an optimized rotation state
LIN_VEL,
ANG_VEL,
}
#copy state to array
func get_state( state, array ):
array[ORIGIN] = state.transform.origin
array[QUAT] = state.transform.basis.get_rotation_quaternion()
array[LIN_VEL] = state.linear_velocity
array[ANG_VEL] = state.angular_velocity
#copy array to state
func set_state( array, state ):
state.transform.origin = array[ORIGIN]
state.transform.basis = Basis( array[QUAT] )
state.linear_velocity = array[LIN_VEL]
state.angular_velocity = array[ANG_VEL]
func get_physics_body_info():
# server copy for sync
get_state( body_state, sync_bstate_array )
func set_physics_body_info():
# client rpc set from server
set_state( sync_bstate_array, body_state )
func _physics_process(_delta):
if is_multiplayer_authority() and sync_object.visible:
frame += 1
sync_bstate_array[FRAME] = frame
get_physics_body_info()
# make sure to wire the "synchronized" signal to this function
func _on_synchronized():
correct_error()
# is this necessary?
if is_previouse_frame():
return
set_physics_body_info()
# very basic network jitter reduction
func correct_error():
var diff :Vector3= body_state.transform.origin - sync_bstate_array[ORIGIN]
# print(name,": diff origin ", diff.length())
# correct minor error, but snap to incoming state if too far from reality
if diff.length() < 3.0:
sync_bstate_array[ORIGIN] = body_state.transform.origin.lerp(sync_bstate_array[ORIGIN],0.05)
func is_previouse_frame() -> bool:
if sync_bstate_array[FRAME] <= last_frame:
return true
else:
last_frame = sync_bstate_array[FRAME]
return false |
Actually looking at the correct_error section in the code above maybe TickInterpolator can work if its set to transform.origin A few comments in other places mention its a hack that lets you mess with the position of a RigidBody |
what would be the property path of transform.origin, because my netfox gives warnings that it's an invalid path also if I put that code above on a player rigidbody it desyncs even on localhost and honestly I'm kinda at a loss as to why |
Are you typing it like
This technically fixes the issue and while there's a definite improvement over no interpolation, it is still quite jumpy and unstable. 1.mp4
Using this implementation, the physics are silky smooth on the client. 2.mp4Adding this _ready function to the code also removes any need for configuration... func _ready():
connect("synchronized", _on_synchronized)
replication_config.add_property("%s:sync_bstate_array" % self.get_path()) |
new-game-project.zip
Netfox: 1.8.0
Godot 4.3
The text was updated successfully, but these errors were encountered: