Help with Optimizing Animated Gun-Skins

I have scripted an animated gun skin system, however, it seems to be very costly on performance dropping my 200+ fps to 100-70 fps.

The animated skin system is quite simple. It manipulates the textures offset which results in a movement effect.

Code
local Players = game:GetService("Players")

local SkinSettings = require(script:WaitForChild("Skin_Settings"))
local X, Y = SkinSettings.X, SkinSettings.Y

local Weapon = script.Parent

local Client = Players.LocalPlayer
local Character = Client.Character

X = X * 0.01; Y = Y * 0.01

local function Update(Texture)
	Texture.OffsetStudsU = (Texture.OffsetStudsU + X) % Texture.StudsPerTileU
	Texture.OffsetStudsV = (Texture.OffsetStudsV + Y) % Texture.StudsPerTileV
end

for _, Texture in pairs(Weapon:GetDescendants()) do 
	if Texture:IsA("Texture") and Texture.Name == "GunSkinTexture" then
		coroutine.wrap(function()
			while task.wait(1 / 30) do 
				if Weapon.Parent ~= Character then
					continue
				end
				Update(Texture) 
			end
		end)()
	end
end

Is there any other method behind animated gun skins, or any way to optimize this code better?
I did try tweenservice, and the lag was the same. Keep in mind, my guns have many parts and textures, so I understand why it lags.

1 Like

The most obvious problem is that your wait amount is tiny (0.03!), and using waits that small is bad for performance in general. You’re also doing division to get that number, which would take even longer.

With that being said, does performance start to drop after only animating one gun, or multiple? If it was a problem with having too many animated guns, it’s possible you could stop the gun skin animation when it is outside of the player’s view, or they are too far away to see anyway.

Adding onto this, you can easily do the latter by enabling streamingenabled in workspace, and lowering the distance, mode depends on what type of game, i’d research it

1 Like