Iamhere345
(snake_case)
December 19, 2022, 1:29am
#1
Hi developers,
I recently inserted a map into my gun system testing place and i began to notice lag spikes every time i shot a gun. Looking at the micro profiler, the graph goes straight up whenever you shoot a gun. This also results in a framerate drop of about ~10 fps.
After looking into i found that this lag spike is caused by changing the size and position of a part (to look like a laser coming out of the barrel of the gun).
This is the offending code, which again is called every time a gun is shot, so multiple times per second:
function utils.visualiseRaycast(origin: Vector3, dir: Vector3?, range: number?, bullet: Part)
bullet.Size = Vector3.new(bullet.Size.X, bullet.Size.Y, range)
bullet.CFrame = CFrame.new(origin, origin + (dir * range)) * CFrame.new(0, 0, -range / 2)
end
task.spawn(function()
local laserPart: Part = bulletCache:GetPart()
laserPart.Color = bulletColour
utils.visualiseRaycast(origin, dir, length or gunInfo.stats.range, laserPart)
task.wait(duration)
bulletCache:ReturnPart(laserPart)
end)
(partcache is a module that caches parts to be used multiple times, see: PartCache, for all your quick part-creation needs )
So if the issue is changing the size and position of a part, how can i optimise this so the there is no lag or the lag is negligible?
Also, the lag gets more noticeable the more parts are in the game (i.e a high detail map makes the gun system lag heaps).
You can see for yourself here (make sure to turn on the micro profiler): TPS - Roblox
Thanks,
- snake_case
1 Like
Maybe instead of creating the bullet every time you shoot you clone a model in server storage instead.
Iamhere345
(snake_case)
December 19, 2022, 2:21am
#3
It doesn’t create a part each time, instead it gets an existing part from a pool of parts. Thats what the PartCache:GetPart()
function does.
Then uh. Sorry, I don’t know much.
Iamhere345
(snake_case)
December 19, 2022, 9:58pm
#5
after doing some more research, it seems that changing the size of the part is whats causing the lag, not changing the position, which makes sense, because manipulating CFrames is cheap (and rightly so), but changing the size is changing the geometry of the instance, which would be more expensive that setting the CFrame. So now the question is, how do i optimise changing the size of parts multiple times per second?
DataSigh
(DataSigh)
December 19, 2022, 10:04pm
#6
The issue is probably something else unrelated to changing the size of the part, what other operations are you doing in your code when shooting the gun?
Iamhere345
(snake_case)
December 19, 2022, 10:06pm
#7
A raycast, as well as setting the position of another PartCache’d part to the barrel of the gun and enabling a light and playing a sound on that.
This is the shooting function (also this is on the client):
function utils.standardFire(self, gunInfo, gunModel, fireAnim: AnimationTrack, ammo, fxHandler: () -> nil, fireInputString: string, serverInputParams: {any}, inputResultHandler: ({any}) -> nil)
task.wait()
if tick() - self.lastShot <= gunInfo.stats.firerate / (60 * 60) and self.lastShot ~= 0 then
return
end
self.lastShot = tick()
ammo:decrement()
task.spawn(function()
fireAnim:Play()
-- sound and light fx
fxHandler()
local result = table.pack(remotes.inputFunction:InvokeServer(fireInputString, unpack(serverInputParams)))
inputResultHandler(result)
end)
self.lastShot = tick()
return true
end
and this is what that fxHandler
function is calling:
function utils.standardFx(gunModel: Model, gunInfo: {}, origin: Vector3, dir: Vector3, length: number, fxCache: {}, bulletCache: {}, lightName: string, soundName: string, duration: number, bulletColour: Color3)
task.spawn(function()
local fxPart: Part = fxCache:GetPart()
fxPart.Position = gunModel.PrimaryPart.Position
local soundDone, lightDone = false, false
local partLight: PointLight = fxPart[lightName]
partLight.Enabled = true
local partSound: Sound = fxPart[soundName]
partSound:Play()
partSound.Ended:Once(function()
soundDone = true
end)
task.wait(duration)
partLight.Enabled = false
lightDone = true
repeat task.wait() until soundDone and lightDone
fxCache:ReturnPart(fxPart)
end)
-- show laser
task.spawn(function()
local laserPart: Part = bulletCache:GetPart()
laserPart.Color = bulletColour
--[[local rayParams = RaycastParams.new()
rayParams.FilterType = Enum.RaycastFilterType.Blacklist
rayParams.FilterDescendantsInstances = {workspace.FxContainer, game.Players.LocalPlayer.Character}
local clientRaycast = workspace:Raycast(origin, dir * gunInfo.stats.range, rayParams)]]
utils.visualiseRaycast(origin, dir, length or gunInfo.stats.range, laserPart)
task.wait(duration)
bulletCache:ReturnPart(laserPart)
end)
end
Iamhere345
(snake_case)
December 19, 2022, 11:25pm
#8
The reason i think the issue is changing the size of these parts is because when i comment out the line that changes the size of the part the lag spikes disappear.
Iamhere345
(snake_case)
December 20, 2022, 5:13am
#9
I ended up replacing the parts with a beam. The lag spikes have stopped.
system
(system)
Closed
January 3, 2023, 5:13am
#10
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.