Repeatedly tweening a model causing frame drops

Hey Developers,

I would like to repeatedly clone and tween this model smoothly without any frame drops, however when attempting to achieve this I come across an issue where my frames will drop. This issue only occurs on PC - mobile players do not experience these frame drops.

Originally I tried moving the loop and tweens onto the client to reduce lag on the server. This reduced server lag but now we have more client-sided lag, I then tried to move the loop onto the server and kept the tweens on the client which did not reduce frame drops on PC clients. After some research, I later found out that mobile players do not experience the same frame dropping as PC players.

Here’s a video showing the frame drops when the code is running.
https://streamable.com/7i6jwx

Server Code:

function StandControlModule.CreateArms(Character)
	local Root = Character.HumanoidRootPart
	local CurrentStand = Character:FindFirstChildOfClass("Model") -- The model that carries out this specific move
	local BarrageValue = Character.CharacterValues.Barraging -- Checks if Character is using the Move
	
	local BarrageArmFolder = game.ServerStorage.BarrageArms -- Where the arm models are being stored 
	local BarrageArm = BarrageArmFolder:FindFirstChild(CurrentStand.Name.."Arm") -- The arm itself

	local DebrisTime = 0.4 -- How long the arm is in game
	if CurrentStand == nil then return end -- Checks if the Model is still active during the move
	if BarrageArm == false then return end 

	while BarrageValue.Value == true  do

		local pivotCFrame = CurrentStand.HumanoidRootPart.CFrame * CFrame.new(0, .5, -6)

		-- primary parts

-- Yes both arms are named "Left Arm" they just position differently 

		local leftLA = BarrageArm["Left Arm"]:Clone()
		leftLA.Transparency = 0
		leftLA.CanCollide = false
		leftLA.Anchored = true
		leftLA.Parent = Root
		Debris:AddItem(leftLA, DebrisTime)

		local rightLA = BarrageArm["Left Arm"]:Clone()
		rightLA.Transparency = 0
		rightLA.CanCollide = false
		rightLA.Anchored = true
		rightLA.Parent = Root
		Debris:AddItem(rightLA, DebrisTime)

		-- primary CFrames
		leftLA.CFrame = CFrame.new((CurrentStand.HumanoidRootPart.CFrame * CFrame.new(math.random(160,350)/100 * -1, math.random(-150,250)/100, -1.5)).p, pivotCFrame.p) * CFrame.Angles(math.rad(90), 0,0)
		rightLA.CFrame = CFrame.new((CurrentStand.HumanoidRootPart.CFrame * CFrame.new(math.random(160,350)/100, math.random(-150,250)/100, -1.5)).p, pivotCFrame.p) * CFrame.Angles(math.rad(90), 0,0)

		
		local arm1 = rightLA
		local arm2 = leftLA
		
		game.ReplicatedStorage.RemoteEvents.ClientEffects:FireAllClients("BarrageArms", arm1, arm2) -- fires remote event to send Arm instances to the client for tweening
		
		wait(0.2)
		
	end
end

Client Code:

local Players = game:GetService("Players")
local plr = Players.LocalPlayer
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local EventsFolder = ReplicatedStorage:FindFirstChild("RemoteEvents")
local ClientEffects = EventsFolder:FindFirstChild("ClientEffects")
local TweenService = game:GetService("TweenService")

ClientEffects.OnClientEvent:Connect(function(type1, arg2, arg3, arg4)
	if type1 == "BarrageArms" then
		BarrageArms(arg2, arg3)
end)

function BarrageArms(arm1, arm2)
	local DebrisTime = 0.4
	local tween1 = TweenService:Create(arm2, TweenInfo.new(DebrisTime), 	{CFrame = arm2.CFrame * CFrame.new(0,-5,0)}) -- Creates a tween which moves the Arm forward
	local tween2 = TweenService:Create(arm1, TweenInfo.new(DebrisTime),	{CFrame = arm1.CFrame * CFrame.new(0,-5,0)}) -- Creates a tween which moves the Arm forward
		
	tween1:Play() -- Plays the tween
	tween2:Play()

	wait(0.2)
end

Thank you for taking your time to read this post, I hope you can help me achieve my goal. Feel free to ask any questions.

1 Like

Your code looks perfectly fine. The best thing I’d suggest doing are trying out some optimizations that may or may not work. Here are a few that I can think of:

  • Instead of creating and destroying the parts immediately, just create them then store them in a table somewhere and load them in whenever you’re doing the animation, something like a PartCache
  • Try setting the parent of the fake arms into workspace instead of the HumanoidRootPart since it is possible that the Humanoid is doing some unknown extra calculations on the fake arms
  • It could be possible that your meshes/arms have a very high poly or vertices count (like 3k+). Try reducing the number of trigs (triangles) in those meshes
  • Turn off all collision on the fake arms, including CanCollide, CanTouch, and CanQuery
  • If all else fails, try using :BulkMoveTo() with eventMode FireCFrameChanged
2 Likes