Elevator shaking visibly while moving

So I had been experiencing this issue and my initial decision was to separate the functional elevator and the visual elevator into client/server. The visual elevator is client based and applies to all clients but is rendered by each player, but physical movement is server based so multiple players can ride the same elevator. This solved the problem of the player shaking and falling because now the invisible physical elevator doesn’t shake. The problem I’m now facing is the VISUAL elevator, the one with collisions off, is shaking while it moves. This is, as I understand it, a very common problem with roblox elevators but I was assuming that combining most of the small parts into a mesh would solve the rendering problem, but it did not. I will provide the scripts here so you can see the relation of the client and server scripts, and I’ve labeled the sections for visibility.

Server Script:

local TweenService = game:GetService("TweenService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

---------------------------------------------------
-- REMOTE EVENT
---------------------------------------------------
local moveEvent =
	ReplicatedStorage:WaitForChild(
		"ServiceLift2_MoveEvent"
	)

---------------------------------------------------
-- SERVER ELEVATOR
---------------------------------------------------

local elevator =
	workspace:WaitForChild(
		"ServiceElevator2_Server"
	)

---------------------------------------------------
-- ROOT PART
---------------------------------------------------

local rootPart =
	elevator:WaitForChild(
		"RootPart"
	)

elevator.PrimaryPart = rootPart

---------------------------------------------------
-- FLOOR POSITIONS
---------------------------------------------------

local floor1Pos =
	workspace:WaitForChild(
		"ServiceElevator2FloorPosition1"
	)

local floor2Pos =
	workspace:WaitForChild(
		"ServiceElevator2FloorPosition2"
	)

---------------------------------------------------
-- BUTTONS
---------------------------------------------------

local floor1Button =
	elevator:WaitForChild(
		"FloorOneButton"
	).ClickDetector

local floor2Button =
	elevator:WaitForChild(
		"FloorTwoButton"
	).ClickDetector

---------------------------------------------------
-- FLOOR 1 CALL BUTTON
---------------------------------------------------

local callButton =
	workspace:WaitForChild(
		"CallButtonServiceElevator2"
	).ClickDetector

---------------------------------------------------
-- FLOOR 2 CALL BUTTON
---------------------------------------------------

local callButton2 =
	workspace:WaitForChild(
		"CallButton2ServiceElevator2"
	).ClickDetector

---------------------------------------------------
-- SERVER DOORS
---------------------------------------------------

local insideLeft =
	elevator:WaitForChild(
		"InsideDoorLeft"
	)

local insideRight =
	elevator:WaitForChild(
		"InsideDoorRight"
	)

---------------------------------------------------
-- SETTINGS
---------------------------------------------------

local MOVE_TIME = 20
local DOOR_TIME = 1.5

local moving = false
local currentFloor = 1

---------------------------------------------------
-- SAVE OPEN POSITIONS
---------------------------------------------------

local insideLeftOpen =
	insideLeft:GetPivot()

local insideRightOpen =
	insideRight:GetPivot()

---------------------------------------------------
-- CLOSED POSITIONS
---------------------------------------------------

local insideLeftClosed =
	insideLeftOpen
	* CFrame.Angles(0, math.rad(90), 0)

local insideRightClosed =
	insideRightOpen
	* CFrame.Angles(0, math.rad(-90), 0)

---------------------------------------------------
-- DOOR TWEEN
---------------------------------------------------

local function tweenDoor(
	model,
	targetCF
)

	local value =
		Instance.new("CFrameValue")

	value.Value =
		model:GetPivot()

	local connection =
		value:GetPropertyChangedSignal(
			"Value"
		):Connect(function()

		model:PivotTo(
			value.Value
		)

	end)

	local tween = TweenService:Create(
		value,
		TweenInfo.new(
			DOOR_TIME,
			Enum.EasingStyle.Sine,
			Enum.EasingDirection.InOut
		),
		{
			Value = targetCF
		}
	)

	tween:Play()
	tween.Completed:Wait()

	connection:Disconnect()
	value:Destroy()

end

---------------------------------------------------
-- OPEN DOORS
---------------------------------------------------

local function openDoors()

	task.spawn(function()

		tweenDoor(
			insideLeft,
			insideLeftOpen
		)

	end)

	task.spawn(function()

		tweenDoor(
			insideRight,
			insideRightOpen
		)

	end)

end

---------------------------------------------------
-- CLOSE DOORS
---------------------------------------------------

local function closeDoors()

	task.spawn(function()

		tweenDoor(
			insideLeft,
			insideLeftClosed
		)

	end)

	task.spawn(function()

		tweenDoor(
			insideRight,
			insideRightClosed
		)

	end)

	wait(DOOR_TIME)

end

---------------------------------------------------
-- MOVE ELEVATOR
---------------------------------------------------

local function moveElevator(
	targetPart,
	targetFloor
)

	if moving then
		return
	end

	moving = true

	------------------------------------------------
	-- CLOSE SERVER DOORS
	------------------------------------------------

	closeDoors()

	------------------------------------------------
	-- SAVE START POSITION
	------------------------------------------------

	local startCF =
		rootPart.CFrame

	------------------------------------------------
	-- TELL CLIENTS TO CLOSE DOORS
	------------------------------------------------

	moveEvent:FireAllClients(
		"CloseDoors"
	)

	------------------------------------------------
	-- WAIT FOR CLIENT DOORS
	------------------------------------------------

	wait(DOOR_TIME)

	------------------------------------------------
	-- MOVE REAL ELEVATOR
	------------------------------------------------

	local value =
		Instance.new("CFrameValue")

	value.Value =
		startCF

	local connection =
		value:GetPropertyChangedSignal(
			"Value"
		):Connect(function()

		elevator:PivotTo(
			value.Value
		)

	end)

	local tween = TweenService:Create(
		value,
		TweenInfo.new(
			MOVE_TIME,
			Enum.EasingStyle.Sine,
			Enum.EasingDirection.InOut
		),
		{
			Value = targetPart.CFrame
		}
	)

	------------------------------------------------
	-- START CLIENT MIRRORING
	------------------------------------------------

	moveEvent:FireAllClients(
		"MoveElevator",
		startCF,
		targetPart.CFrame,
		MOVE_TIME,
		targetFloor
	)

	------------------------------------------------
	-- WAIT ONE FRAME
	------------------------------------------------

	task.wait()

	------------------------------------------------
	-- START SERVER MOVEMENT
	------------------------------------------------

	tween:Play()

	------------------------------------------------
	-- WAIT FOR COMPLETION
	------------------------------------------------

	tween.Completed:Wait()

	connection:Disconnect()
	value:Destroy()

	currentFloor = targetFloor

	wait(0.5)

	------------------------------------------------
	-- OPEN SERVER DOORS
	------------------------------------------------

	openDoors()

	------------------------------------------------
	-- TELL CLIENTS TO OPEN DOORS
	------------------------------------------------

	moveEvent:FireAllClients(
		"OpenDoors",
		nil,
		nil,
		nil,
		targetFloor
	)

	moving = false

end

---------------------------------------------------
-- INSIDE BUTTONS
---------------------------------------------------

floor2Button.MouseClick:Connect(function()

	if currentFloor == 1 then

		moveElevator(
			floor2Pos,
			2
		)

	end

end)

floor1Button.MouseClick:Connect(function()

	if currentFloor == 2 then

		moveElevator(
			floor1Pos,
			1
		)

	end

end)

---------------------------------------------------
-- FLOOR 1 CALL BUTTON
---------------------------------------------------

callButton.MouseClick:Connect(function()

	if currentFloor == 2 then

		moveElevator(
			floor1Pos,
			1
		)

	end

end)

---------------------------------------------------
-- FLOOR 2 CALL BUTTON
---------------------------------------------------

callButton2.MouseClick:Connect(function()

	if currentFloor == 1 then

		moveElevator(
			floor2Pos,
			2
		)

	end

end)

---------------------------------------------------
-- START OPEN
---------------------------------------------------

insideLeft:PivotTo(
	insideLeftOpen
)

insideRight:PivotTo(
	insideRightOpen
)

ClientScript:

local TweenService = game:GetService("TweenService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")

---------------------------------------------------
-- REMOTE EVENT
---------------------------------------------------

local moveEvent =
	ReplicatedStorage:WaitForChild(
		"ServiceLift2_MoveEvent"
	)

---------------------------------------------------
-- VISUAL ELEVATOR
---------------------------------------------------

local elevator =
	workspace:WaitForChild(
		"ServiceElevator2_Visual"
	)

---------------------------------------------------
-- SERVER ELEVATOR
---------------------------------------------------

local serverElevator =
	workspace:WaitForChild(
		"ServiceElevator2_Server"
	)

---------------------------------------------------
-- ROOT PARTS
---------------------------------------------------

local visualRoot =
	elevator:WaitForChild(
		"RootPart"
	)

local serverRoot =
	serverElevator:WaitForChild(
		"RootPart"
	)

elevator.PrimaryPart =
	visualRoot

serverElevator.PrimaryPart =
	serverRoot

---------------------------------------------------
-- VISUAL DOORS
---------------------------------------------------

local insideLeft =
	elevator:WaitForChild(
		"InsideDoorLeft"
	)

local insideRight =
	elevator:WaitForChild(
		"InsideDoorRight"
	)

---------------------------------------------------
-- OUTSIDE DOORS
---------------------------------------------------

local outsideLeft =
	workspace:WaitForChild(
		"ServiceElevator2OutsideDoorLeft"
	)

local outsideRight =
	workspace:WaitForChild(
		"ServiceElevator2OutsideDoorRight"
	)

---------------------------------------------------
-- SETTINGS
---------------------------------------------------

local DOOR_TIME = 1.5

---------------------------------------------------
-- RELATIVE INSIDE DOOR OFFSETS
---------------------------------------------------

local insideLeftOpenOffset =
	elevator.PrimaryPart.CFrame:ToObjectSpace(
		insideLeft:GetPivot()
	)

local insideRightOpenOffset =
	elevator.PrimaryPart.CFrame:ToObjectSpace(
		insideRight:GetPivot()
	)

local insideLeftClosedOffset =
	insideLeftOpenOffset
	* CFrame.Angles(0, math.rad(90), 0)

local insideRightClosedOffset =
	insideRightOpenOffset
	* CFrame.Angles(0, math.rad(-90), 0)

---------------------------------------------------
-- OUTSIDE DOOR POSITIONS
---------------------------------------------------

local outsideLeftOpen =
	outsideLeft:GetPivot()

local outsideRightOpen =
	outsideRight:GetPivot()

local outsideLeftClosed =
	outsideLeftOpen
	* CFrame.Angles(0, math.rad(-90), 0)

local outsideRightClosed =
	outsideRightOpen
	* CFrame.Angles(0, math.rad(90), 0)

---------------------------------------------------
-- GET INSIDE DOOR POSITIONS
---------------------------------------------------

local function getInsideLeftOpen()

	return elevator.PrimaryPart.CFrame
		* insideLeftOpenOffset

end

local function getInsideRightOpen()

	return elevator.PrimaryPart.CFrame
		* insideRightOpenOffset

end

local function getInsideLeftClosed()

	return elevator.PrimaryPart.CFrame
		* insideLeftClosedOffset

end

local function getInsideRightClosed()

	return elevator.PrimaryPart.CFrame
		* insideRightClosedOffset

end

---------------------------------------------------
-- DOOR TWEEN
---------------------------------------------------

local function tweenDoor(
	model,
	targetCF
)

	local value =
		Instance.new("CFrameValue")

	value.Value =
		model:GetPivot()

	local connection =
		value:GetPropertyChangedSignal(
			"Value"
		):Connect(function()

		model:PivotTo(
			value.Value
		)

	end)

	local tween = TweenService:Create(
		value,
		TweenInfo.new(
			DOOR_TIME,
			Enum.EasingStyle.Sine,
			Enum.EasingDirection.InOut
		),
		{
			Value = targetCF
		}
	)

	tween:Play()
	tween.Completed:Wait()

	connection:Disconnect()
	value:Destroy()

end

---------------------------------------------------
-- OPEN DOORS
---------------------------------------------------

local function openDoors(
	targetFloor
)

	task.spawn(function()

		tweenDoor(
			insideLeft,
			getInsideLeftOpen()
		)

	end)

	task.spawn(function()

		tweenDoor(
			insideRight,
			getInsideRightOpen()
		)

	end)

	if targetFloor == 1 then

		task.spawn(function()

			tweenDoor(
				outsideLeft,
				outsideLeftOpen
			)

		end)

		task.spawn(function()

			tweenDoor(
				outsideRight,
				outsideRightOpen
			)

		end)

	end

end

---------------------------------------------------
-- CLOSE DOORS
---------------------------------------------------

local function closeDoors()

	task.spawn(function()

		tweenDoor(
			insideLeft,
			getInsideLeftClosed()
		)

	end)

	task.spawn(function()

		tweenDoor(
			insideRight,
			getInsideRightClosed()
		)

	end)

	task.spawn(function()

		tweenDoor(
			outsideLeft,
			outsideLeftClosed
		)

	end)

	task.spawn(function()

		tweenDoor(
			outsideRight,
			outsideRightClosed
		)

	end)

end

---------------------------------------------------
-- RECEIVE EVENTS
---------------------------------------------------

moveEvent.OnClientEvent:Connect(function(
	action,
	startCF,
	endCF,
	moveTime,
	targetFloor
)

	if action == "CloseDoors" then

		closeDoors()

	end

	if action == "MoveElevator" then

		local renderConnection

		renderConnection =
			RunService.RenderStepped:Connect(function()

				elevator:PivotTo(
					serverElevator:GetPivot()
				)

			end)

		task.wait(moveTime)

		renderConnection:Disconnect()

		local offset =
			elevator.PrimaryPart.CFrame:Inverse()
			* elevator:GetPivot()

		elevator:PivotTo(
			serverRoot.CFrame * offset
		)

	end

	if action == "OpenDoors" then

		openDoors(targetFloor)

	end

end)

Try replacing RunService.RenderStepped:Connect with RunService:BindToSimulation, I don’t know if it will work I’m just curious..
You’ll need Workspace.UseFixedSimulationenabled though if it isn’t already

I went to work and tried that out and I’m still seeing the same noticeable shaking in the elevator

Client Script

local TweenService = game:GetService("TweenService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

---------------------------------------------------
-- REMOTE EVENT
---------------------------------------------------

local moveEvent =
	ReplicatedStorage:WaitForChild(
		"ServiceLift2_MoveEvent"
	)

---------------------------------------------------
-- VISUAL ELEVATOR
---------------------------------------------------

local elevator =
	workspace:WaitForChild(
		"ServiceElevator2_Visual"
	)

---------------------------------------------------
-- ROOT PART
---------------------------------------------------

local visualRoot =
	elevator:WaitForChild(
		"RootPart"
	)

elevator.PrimaryPart =
	visualRoot

---------------------------------------------------
-- VISUAL DOORS
---------------------------------------------------

local insideLeft =
	elevator:WaitForChild(
		"InsideDoorLeft"
	)

local insideRight =
	elevator:WaitForChild(
		"InsideDoorRight"
	)

---------------------------------------------------
-- OUTSIDE DOORS
---------------------------------------------------

local outsideLeft =
	workspace:WaitForChild(
		"ServiceElevator2OutsideDoorLeft"
	)

local outsideRight =
	workspace:WaitForChild(
		"ServiceElevator2OutsideDoorRight"
	)

---------------------------------------------------
-- SETTINGS
---------------------------------------------------

local DOOR_TIME = 1.5

---------------------------------------------------
-- RELATIVE INSIDE DOOR OFFSETS
---------------------------------------------------

local insideLeftOpenOffset =
	elevator.PrimaryPart.CFrame:ToObjectSpace(
		insideLeft:GetPivot()
	)

local insideRightOpenOffset =
	elevator.PrimaryPart.CFrame:ToObjectSpace(
		insideRight:GetPivot()
	)

local insideLeftClosedOffset =
	insideLeftOpenOffset
	* CFrame.Angles(0, math.rad(90), 0)

local insideRightClosedOffset =
	insideRightOpenOffset
	* CFrame.Angles(0, math.rad(-90), 0)

---------------------------------------------------
-- OUTSIDE DOOR POSITIONS
---------------------------------------------------

local outsideLeftOpen =
	outsideLeft:GetPivot()

local outsideRightOpen =
	outsideRight:GetPivot()

local outsideLeftClosed =
	outsideLeftOpen
	* CFrame.Angles(0, math.rad(-90), 0)

local outsideRightClosed =
	outsideRightOpen
	* CFrame.Angles(0, math.rad(90), 0)

---------------------------------------------------
-- GET INSIDE DOOR POSITIONS
---------------------------------------------------

local function getInsideLeftOpen()

	return elevator.PrimaryPart.CFrame
		* insideLeftOpenOffset

end

local function getInsideRightOpen()

	return elevator.PrimaryPart.CFrame
		* insideRightOpenOffset

end

local function getInsideLeftClosed()

	return elevator.PrimaryPart.CFrame
		* insideLeftClosedOffset

end

local function getInsideRightClosed()

	return elevator.PrimaryPart.CFrame
		* insideRightClosedOffset

end

---------------------------------------------------
-- DOOR TWEEN
---------------------------------------------------

local function tweenDoor(
	model,
	targetCF
)

	local value =
		Instance.new("CFrameValue")

	value.Value =
		model:GetPivot()

	local connection =
		value:GetPropertyChangedSignal(
			"Value"
		):Connect(function()

		model:PivotTo(
			value.Value
		)

	end)

	local tween = TweenService:Create(
		value,
		TweenInfo.new(
			DOOR_TIME,
			Enum.EasingStyle.Sine,
			Enum.EasingDirection.InOut
		),
		{
			Value = targetCF
		}
	)

	tween:Play()
	tween.Completed:Wait()

	connection:Disconnect()
	value:Destroy()

end

---------------------------------------------------
-- OPEN DOORS
---------------------------------------------------

local function openDoors(
	targetFloor
)

	task.spawn(function()

		tweenDoor(
			insideLeft,
			getInsideLeftOpen()
		)

	end)

	task.spawn(function()

		tweenDoor(
			insideRight,
			getInsideRightOpen()
		)

	end)

	if targetFloor == 1 then

		task.spawn(function()

			tweenDoor(
				outsideLeft,
				outsideLeftOpen
			)

		end)

		task.spawn(function()

			tweenDoor(
				outsideRight,
				outsideRightOpen
			)

		end)

	end

end

---------------------------------------------------
-- CLOSE DOORS
---------------------------------------------------

local function closeDoors()

	task.spawn(function()

		tweenDoor(
			insideLeft,
			getInsideLeftClosed()
		)

	end)

	task.spawn(function()

		tweenDoor(
			insideRight,
			getInsideRightClosed()
		)

	end)

	task.spawn(function()

		tweenDoor(
			outsideLeft,
			outsideLeftClosed
		)

	end)

	task.spawn(function()

		tweenDoor(
			outsideRight,
			outsideRightClosed
		)

	end)

end

---------------------------------------------------
-- RECEIVE EVENTS
---------------------------------------------------

moveEvent.OnClientEvent:Connect(function(
	action,
	startCF,
	endCF,
	moveTime,
	targetFloor
)

	------------------------------------------------
	-- CLOSE DOORS
	------------------------------------------------

	if action == "CloseDoors" then

		closeDoors()

	end

	------------------------------------------------
	-- MOVE ELEVATOR
	------------------------------------------------

	if action == "MoveElevator" then

		local value =
			Instance.new("CFrameValue")

		value.Value =
			elevator:GetPivot()

		local connection =
			value:GetPropertyChangedSignal(
				"Value"
			):Connect(function()

			elevator:PivotTo(
				value.Value
			)

		end)

		local tween =
			TweenService:Create(
				value,
				TweenInfo.new(
					moveTime,
					Enum.EasingStyle.Sine,
					Enum.EasingDirection.InOut
				),
				{
					Value = endCF
				}
			)

		tween:Play()

		tween.Completed:Wait()

		connection:Disconnect()
		value:Destroy()

	end

	------------------------------------------------
	-- OPEN DOORS
	------------------------------------------------

	if action == "OpenDoors" then

		openDoors(targetFloor)

	end

end)

Server Script

local TweenService = game:GetService("TweenService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")

---------------------------------------------------
-- REMOTE EVENT
---------------------------------------------------

local moveEvent =
	ReplicatedStorage:WaitForChild(
		"ServiceLift2_MoveEvent"
	)

---------------------------------------------------
-- SERVER ELEVATOR
---------------------------------------------------

local elevator =
	workspace:WaitForChild(
		"ServiceElevator2_Server"
	)

---------------------------------------------------
-- ROOT PART
---------------------------------------------------

local rootPart =
	elevator:WaitForChild(
		"RootPart"
	)

elevator.PrimaryPart = rootPart

---------------------------------------------------
-- FLOOR POSITIONS
---------------------------------------------------

local floor1Pos =
	workspace:WaitForChild(
		"ServiceElevator2FloorPosition1"
	)

local floor2Pos =
	workspace:WaitForChild(
		"ServiceElevator2FloorPosition2"
	)

---------------------------------------------------
-- BUTTONS
---------------------------------------------------

local floor1Button =
	elevator:WaitForChild(
		"FloorOneButton"
	).ClickDetector

local floor2Button =
	elevator:WaitForChild(
		"FloorTwoButton"
	).ClickDetector

local callButton =
	workspace:WaitForChild(
		"CallButtonServiceElevator2"
	).ClickDetector

local callButton2 =
	workspace:WaitForChild(
		"CallButton2ServiceElevator2"
	).ClickDetector

---------------------------------------------------
-- SERVER DOORS
---------------------------------------------------

local insideLeft =
	elevator:WaitForChild(
		"InsideDoorLeft"
	)

local insideRight =
	elevator:WaitForChild(
		"InsideDoorRight"
	)

---------------------------------------------------
-- SETTINGS
---------------------------------------------------

local MOVE_TIME = 20
local DOOR_TIME = 1.5

local moving = false
local currentFloor = 1

---------------------------------------------------
-- SAVE OPEN POSITIONS
---------------------------------------------------

local insideLeftOpen =
	insideLeft:GetPivot()

local insideRightOpen =
	insideRight:GetPivot()

---------------------------------------------------
-- CLOSED POSITIONS
---------------------------------------------------

local insideLeftClosed =
	insideLeftOpen
	* CFrame.Angles(0, math.rad(90), 0)

local insideRightClosed =
	insideRightOpen
	* CFrame.Angles(0, math.rad(-90), 0)

---------------------------------------------------
-- DOOR TWEEN
---------------------------------------------------

local function tweenDoor(
	model,
	targetCF
)

	local value =
		Instance.new("CFrameValue")

	value.Value =
		model:GetPivot()

	local connection =
		value:GetPropertyChangedSignal(
			"Value"
		):Connect(function()

		model:PivotTo(
			value.Value
		)

	end)

	local tween =
		TweenService:Create(
			value,
			TweenInfo.new(
				DOOR_TIME,
				Enum.EasingStyle.Sine,
				Enum.EasingDirection.InOut
			),
			{
				Value = targetCF
			}
		)

	tween:Play()
	tween.Completed:Wait()

	connection:Disconnect()
	value:Destroy()

end

---------------------------------------------------
-- OPEN DOORS
---------------------------------------------------

local function openDoors()

	task.spawn(function()

		tweenDoor(
			insideLeft,
			insideLeftOpen
		)

	end)

	task.spawn(function()

		tweenDoor(
			insideRight,
			insideRightOpen
		)

	end)

end

---------------------------------------------------
-- CLOSE DOORS
---------------------------------------------------

local function closeDoors()

	task.spawn(function()

		tweenDoor(
			insideLeft,
			insideLeftClosed
		)

	end)

	task.spawn(function()

		tweenDoor(
			insideRight,
			insideRightClosed
		)

	end)

	wait(DOOR_TIME)

end

---------------------------------------------------
-- MANUAL SMOOTH MOVEMENT
---------------------------------------------------

local function smoothMove(
	targetCF
)

	local startTime =
		tick()

	local startCF =
		elevator:GetPivot()

	local connection

	connection =
		RunService.Heartbeat:Connect(function()

			local elapsed =
			tick() - startTime

			local alpha =
			math.clamp(
				elapsed / MOVE_TIME,
				0,
				1
			)

			------------------------------------------------
			-- SINE EASING IN/OUT
			------------------------------------------------

			local easedAlpha =
			-(math.cos(math.pi * alpha) - 1) / 2

			------------------------------------------------
			-- INTERPOLATE
			------------------------------------------------

			local newCF =
			startCF:Lerp(
				targetCF,
				easedAlpha
			)

			elevator:PivotTo(
				newCF
			)

			------------------------------------------------
			-- FINISH
			------------------------------------------------

			if alpha >= 1 then

				elevator:PivotTo(
					targetCF
				)

				connection:Disconnect()

			end

		end)

	repeat
		task.wait()
	until not connection.Connected

end

---------------------------------------------------
-- MOVE ELEVATOR
---------------------------------------------------

local function moveElevator(
	targetPart,
	targetFloor
)

	if moving then
		return
	end

	moving = true

	------------------------------------------------
	-- CLOSE DOORS
	------------------------------------------------

	closeDoors()

	------------------------------------------------
	-- SAVE START POSITION
	------------------------------------------------

	local startCF =
		elevator:GetPivot()

	------------------------------------------------
	-- TELL CLIENTS TO CLOSE DOORS
	------------------------------------------------

	moveEvent:FireAllClients(
		"CloseDoors"
	)

	wait(DOOR_TIME)

	------------------------------------------------
	-- TELL CLIENTS TO MOVE
	------------------------------------------------

	moveEvent:FireAllClients(
		"MoveElevator",
		startCF,
		targetPart.CFrame,
		MOVE_TIME,
		targetFloor
	)

	------------------------------------------------
	-- MOVE SERVER ELEVATOR
	------------------------------------------------

	smoothMove(
		targetPart.CFrame
	)

	currentFloor =
		targetFloor

	wait(0.5)

	------------------------------------------------
	-- OPEN DOORS
	------------------------------------------------

	openDoors()

	moveEvent:FireAllClients(
		"OpenDoors",
		nil,
		nil,
		nil,
		targetFloor
	)

	moving = false

end

---------------------------------------------------
-- INSIDE BUTTONS
---------------------------------------------------

floor2Button.MouseClick:Connect(function()

	if currentFloor == 1 then

		moveElevator(
			floor2Pos,
			2
		)

	end

end)

floor1Button.MouseClick:Connect(function()

	if currentFloor == 2 then

		moveElevator(
			floor1Pos,
			1
		)

	end

end)

---------------------------------------------------
-- FLOOR 1 CALL BUTTON
---------------------------------------------------

callButton.MouseClick:Connect(function()

	if currentFloor == 2 then

		moveElevator(
			floor1Pos,
			1
		)

	end

end)

---------------------------------------------------
-- FLOOR 2 CALL BUTTON
---------------------------------------------------

callButton2.MouseClick:Connect(function()

	if currentFloor == 1 then

		moveElevator(
			floor2Pos,
			2
		)

	end

end)

---------------------------------------------------
-- START OPEN
---------------------------------------------------

insideLeft:PivotTo(
	insideLeftOpen
)

insideRight:PivotTo(
	insideRightOpen
)
1 Like

Does it still happen even with client-sided tweens??
I’ve heard scary stuff about server-sided tweens being jittery and killing the network traffic, but from what I understood you removed those

Yes both the client and server shake

This approach uses PrismaticConstraint. Not going to say it’s perfect, but you can tinker around with it and get it pretty close. I’ve never been able to remove all the shake, but I got it down a few jitters.
ElevatorPreset.rbxl (66.2 KB)

Okay so there is a huge issue here, you’re tweening on the server. That’ll mess a ton of stuff for high ping players (it’ll jitter like what you’re seeing), and your network receive would be high. What you should do is have the server update the clients on its current state (Like sending an event) and each client tweens on their own. Its just proper design for optimization and smoothness

I agree that tweening is never going to pull this off.. I’ve tried. That’s how I landed on PrismaticConstraints. The trick is getting the math perfect so there isn’t any jitter left. The start and finish end up a bit off from what you expected, so you have to compensate for that. Try to keep the numbers as evenly divisible as possible relative to the move speed.

You got the general point I was trying to make, but tweeting still is the correct method for this.

What I was trying to get across is tweening on the server is the issue here,
Tweening on the server can (and does):

  • Jitter (like you’re seeing, and it’ll be out worse outside of studio)
  • High network usage which could lag players so much more
  • Lag the server if a ton of tweens are running
  • Won’t properly update for super laggy connections

What should be done is something where the server sends an event to all clients to tween the elevator correct on their end. It’ll will stop the jitter and all the negative side effects, and upon load just replicate the position the elevator is at so clients who don’t have it in the right position can have it properly setup. This is also a lot better sync wise ifykwim

2 Likes