Hello everyone.
First of all, I use UE4.27 → can’t run UE5 on my potato pc
I’m trying to make a multiplayer, physics-based grab system where objects move differently depending on their mass. I tried physics handles, but I couldn’t get them to where heavy objects can pivot and rotate when I pull them from a corner; they just move as a whole. So I decided to use constraints instead. Here is my setup:
Let’s define some things first:
“Anchor” is a component parented to a spring arm that uses control rotation; this is the component that the grabbed object is constrained to.
“Hook” is a component that is attached to the grabbed object at the point where it was grabbed. It is used to get an endpoint for a beam effect in Niagara, not important for the physics.
“Grab Component” is the component being grabbed.
I do a trace locally, and if the object can be picked up, I call a grab event on the server:
Everything works great, replicates well, except for one issue: when a client grabs an object and moves it, it flickers for that client only; the server and all other clients see it moving smoothly, but only the client who is grabbing the object sees the object jittering. And jitter happens only when the object is being moved, and especially when moved fast:
(it looks worse in-game than the video, probably because the video is only at 60fps)
I tried detaching the anchor from the spring arm and moving it on tick on the server, but it still flickers for the client who’s grabbing it.
I’d appreciate any help I could get. I’m running out of ideas on how to solve it.
This could make server override the values of local client , unlesss its listen server host, if there is no issue , then try detecting this trace on server and see how it looks
It did make the trace on the server, but this doesn’t really have anything to do with the physics, and it is a listen server.
I think the problem is happening because of server-client latency: because the server is simulating the physics, and the physics constraint is driven by the anchor movement, which is driven by the client’s movement, by the time the physics simulation comes back from the server, the physics constraint target (the anchor) has already moved on the client, causing a sudden correction. I tried using a fake mesh that is interpolated to the real grabbed object’s position and rotation. It’s a lot better, but still not good. I’ll tweak it some more and see.
Update:
I use a fake static mesh that I spawn on the real grabbed object’s transform, and hide the real object onlyon the client who is doing the grabbing. Then, on tick, I send the transform of the real object from the server to the client doing the grabbing, and use that transform to drive the fake mesh, and the fake mesh ended up moving perfectly smoothly without any interpolation needed!
But I’m still not satisfied. What’s bugging me is that the result suggests that the client is indeed trying to move the grabbed object themselves, even though the server is constraining the grabbed object to its version of the client’s anchor and simulating the physics, so the grabbed object is expected to lag a little (to wait for the server to send back the simulation result), but not jitter. Jitter happens when the object’s transform is being set twice every frame to two slightly different transforms, but the client has physics simulation for the grabbed object OFF; so there is no apparent reason why the client would fight the server over the grabbed component’s transform.
So using the fake mesh is really just a workaround and not a solution.
Control rotation is replicated which handles the movement of the attached actor. That being said you’re always going to be fighting the server.
Each proxy should handle the movement based on the replicated control rotation. Don’t replicate movement of the actor, because the movement of the character is already replicated.