I decided to use SetPrimaryPartCFrame() for an elevator in a building I’m working on because it’s something rather new and I wanted to test it out. However, as soon as I tested it out, I realized it’s very choppy.
I’m assuming this is a bug because it would only make sense that if you move the primary part, all the other parts would move instantly. It appears there’s a short delay in-between each part’s movement.
Note: this is only happening in a server, NOT studio.
GIF to show what’s happening:
I’ll probably end up using an alternative to this method, but I wanted to mention it so that it could possibly be fixed in the future.
if level > currentFloor then
repeat
wait(0)
elevator:SetPrimaryPartCFrame(CFrame.new(elevator.PrimaryPart.Position + Vector3.new(0,0.1,0))*CFrame.Angles(0,math.rad(180),0))
until
elevator.PrimaryPart.Position.Y > script.Parent:findFirstChild("Floor"..targetLevel).Position.Y
Reset()
end
Since you’re using wait(0) it isn’t synced up to rendering - this may be why it’s awkward.
Personally, I would use something like this, on the client:
local floorCFs = {} -- table of levels referring to floors
function navigateToFloor(floorNum)
local endPos = floorCFs[floorNum]
local startPos = elevator.PrimaryPart:GetRenderCFrame()
local t = tick()
local percent = 0
local conn
conn = game:GetService("RunService").RenderStepped:connect(function()
local delta = tick() - t
percent = percent + delta
if percent >= 1 then
elevator:SetPrimaryPartCFrame(endPos)
conn:disconnect()
else
elevator:SetPrimaryPartCFrame(startPos:lerp(endPos, percent))
end
t = tick()
end)
end
This way, you make sure that it runs smoothly on every client (in theory)
I was thinking this too, but I’m only setting one part’s CFrame, not each of the individually. Since it’s moving the primary part, it’s technically moving the model as well, so it should be in sync not each part individually.
I find BodyPositions unreliable. I didn’t want to do what everyone else does with elevators because I always see them drift out of realignment/get stuck.
Here’s what I do, and I mentioned it to Defaultio and he implemented it practically right away for the bridge in LT2: weld all the parts in the elevator to a central part using Motor6D, and unanchor all but that central part. Instead of CFraming an n number of parts that have to replicate, you’re only CFraming 1 part that the clients can then fill in the gaps for the rest of the elevator.
I just used a BodyPosition for an elevator I made.
The only problem is: shared physics.
If there are multiple players in the elevator, it’s very buggy.
I solved this by (temporary) setting the character’s physics to be owned by the server.
(Granted, they can’t move during this time, but it’s just a short elevator ride anyway)
Very smooth indeed.
How do you think the rest of the parts get moved? SetPrimaryPartCFrame probably calls a C-side loop that translates the rest of the parts with the same matrix that the primary part was translated.