Runservice PivotTo() issue

I have the following piece of code to animate some eggs jumping out of my character model. This script is in serverscriptservice. The first time i execute the function everything works fine. But the nit starts bugging out like crazy. I’ve noticed this issue specifically appears when i change my fps in game, but when i rejoin and dont change my fps, everything will work fine. Obviously I can’t just keep this issue in. How would i fix this issue?

local function arcPosition(startPos: CFrame, endPos: CFrame, t: number, height: number)
	local midPoint = (startPos.Position + endPos.Position) / 2
	midPoint += Vector3.new(0, height, 0)
	
	local lerp1 = startPos.Position:Lerp(midPoint, t)
	local lerp2 = midPoint:Lerp(endPos.Position, t)
	return CFrame.new(lerp1:Lerp(lerp2, t))
end

function EggHandler.OpenEgg(plr: Player, eggName: string, amount: number)
	local humanoidPart: Part = plr.Character and plr.Character:FindFirstChild("HumanoidRootPart")
	local distance: number = 10
	local totalTime: number = 0.75
	for i = 1, amount do
		task.spawn(function()
			local egg: Model = eggModels[eggName]:Clone()
			egg.Parent = workspace.EggOpenings
			
			for _, part in pairs(egg:GetDescendants()) do
				if part:IsA("BasePart") then
					part.Anchored = false
					local weld = Instance.new("WeldConstraint")
					weld.Part0 = egg.PrimaryPart
					weld.Part1 = part
					weld.Parent = egg.PrimaryPart
				end
			end
			
			local angle: number = math.rad(360 / amount) * i

			local positionX = humanoidPart.Position.X + (distance * math.cos(angle))
			local positionZ = humanoidPart.Position.Z + (distance * math.sin(angle))

			local endPosition = CFrame.new(positionX, humanoidPart.Position.Y, positionZ)
			
			-- Animation
			local start = tick()
			local eTime = 0
			
			local pos = Instance.new("CFrameValue")
			pos.Value = humanoidPart.CFrame
			
			
			local animConnection: RBXScriptConnection
			local positionConnection: RBXScriptConnection
			local destroyConnection: RBXScriptConnection
			
			positionConnection = runSerivice.Heartbeat:Connect(function()
				egg:PivotTo(pos.Value)
			end)
			animConnection = runSerivice.Heartbeat:Connect(function()
				eTime = tick() - start
				local t = math.min(eTime / totalTime, 1)
				
				if eTime >= totalTime then
					animConnection:Disconnect()
				end
				
				--if t >= 1 then
				--	pos.Value = endPosition
				--	animConnection:Disconnect()
				--	return
				--end
				
				
				local newPos = arcPosition(humanoidPart.CFrame, endPosition, t, 20)
				pos.Value = newPos
			end)
			destroyConnection = egg:GetPropertyChangedSignal("Parent"):Once(function()
				positionConnection:Disconnect()
			end)
		end)
		task.wait(0.2)
	end
	
	task.delay(10, function()
		workspace.EggOpenings:ClearAllChildren()
	end)
end

It seems to me the issue is at least related to the CFrameValue.
Because of this you are also using multiple heartbeat connections. That might also make things choppy.
But you don’t actually need it. Here’s an improved version using only one heartbeat connection:

positionConnection = runSerivice.Heartbeat:Connect(function()
	eTime = tick() - start
	local t = math.min(eTime / totalTime, 1)
				
	if eTime >= totalTime then
		positionConnection:Disconnect()
	end
				
	local newPos = arcPosition(humanoidPart.CFrame, endPosition, t, 20)
	egg:PivotTo(newPos)
end)

Let me know if my changes do anything to resolve your issue.

Best regards,
Pinker

I ended up figuring out that you should not animate on the server. To anyone, don’t do it.

1 Like