CFrame Movement Laggy

So I am moving some models using SetPrimaryPartCFrame, but have discovered that it is somewhat laggy when I move the models with enough speed. Is there a better alternative to move models around without getting choppy / laggy movement?

Notes:

  1. The models are moved via a server script since they are server side objects that are being moved.
  2. I need fairly precise movement and speed, which is why I am using CFrames to move models in the first place.
2 Likes

It has nothing to do with SetPrimaryPartCFrame, it probably has to do with the loop you’re using to move it, send some code please, that’s really what we need, not to mention the fact that since it’s on the server, it won’t update at 60 fps for the players, since the server can’t send to the player and the player can’t receive every frame.

2 Likes

If you’re moving via CFrame and want to do it smoothly, then you need to do it with RenderStep, but that has to happen on the client.

If moving on the server, then utilize the physics engine (e.g. body movers), which the clients will then properly interpolate in-game as the server replicates the changes.

8 Likes

I think Heartbeat is the proper thing to use, RenderStepped is only supposed to be used for camera stuff afaik.

You could do something like

RunService.Heartbeat:Connect(function(d)
 model:SetPrimaryPartCFrame(model:GetPrimaryPartCFrame():lerp(whateverCFrameYouWant, d*10))
end)

And that will move it smoothly enough. You can change d*10 to change how fast you want it to move

3 Likes

Don’t use SetPrimaryPartCFrame. Just weld constraint all the parts to the primary part and set the primary part’s CFrame.

8 Likes

The server can only send updates to the clients at 20Hz (or 20 times per second) which is why you get the choppy movement when cframing on the server.

As the others have said, either use bodymovers to move your objects (in which case the physics engine will interpolate the positions for you) or you CFrame the objects yourself on the clients.

2 Likes

If you want something to be smooth, then it needs to be synced to when the camera updates. If it’s out of sync with rendering (i.e. the camera), then it won’t look smooth.

Ideally I wouldn’t want to move a whole model continuously on renderstep, but it would at least make it look smooth

1 Like

That’s why I added in the damping, it’s a good balance of performance and looks.

I used it in a new game of mine too, so I just move the entire model using a custom “SetPrimaryPartCFrame” function and put it inside Heartbeat so the parts in it don’t start getting dislocated relative to the primary part.

3 Likes

Is Heartbeat something that can be run in a server script, or does it need to be in a local script?

Pretty sure everything but render step fires serverside.

1 Like

This is correct. The server doesn’t need to render anything, but it does have normal steps and heartbeats.

1 Like

This reply I made to a previous post is relevant.

Here it is quoted:
Example

Code:

local model = workspace.Model

local angle = 0

while true do
	for i = 1, 100 do  -- repeat 100 time to exaggerate the effect so it can be seen in a 30 sec video
		model:SetPrimaryPartCFrame(CFrame.new(0, 10, 0)*CFrame.Angles(0, math.rad(angle), 0))
		angle = (angle + 0.1)%360
	end
	wait()
end



I also made a really long post with various examples of how to set up and move models, including place file examples you can inspect and mess with:


Ultimately you’ll either need to use physics or set the CFrame on the client. If you set the CFrame from the server, you’ll be updating it at 20 times a second but the framerate will be 60 times a second so it will be choppy. That might be a fair tradeoff though, if using physics or setting the CFrame on the client is not possible.


If anyone goes this route, the most important part is the custom “SetPrimaryPartCFrame” function. Whether you move things on Heartbeat or Stepped or RenderStepped or just in a loop with wait() doesn’t matter. If you use the built in SetPrimaryPartCFrame then parts will drift over time. If you use a custom one that saves the offsets between parts at the beginning then the parts won’t drift.

7 Likes