I’m currently trying to create the firing portion of an FPS system, e.g. muzzle flash/projectiles. What I want is the muzzle flash VFX and tracer to originate from a part called Flame (which is welded to the gun) for every shot. Everything works when the gun is on semi-automatic mode, however when switching to fully automatic (which uses a while loop) the muzzle flash VFX and tracer’s origin remain the same as when the loop began. I’ve tried using task.spawn to start the loop in a new thread to no avail (but I’ll remain using task.spawn as without it it delays the next shot because of the lag to create a new projectile). I’ve also tried extracting the origin’s CFrame to a function which didn’t work. I’ve tried to search for this issue on Dev Forums but couldn’t find anything on it because it’s kind of hard to explain.
Here is my intended result.
Here is what I’m getting.
Here’s my code (it’s compiled from TypeScript, that’s why variable naming is odd):
CreateFireFX = function(self, suppressed)
if suppressed == nil then
suppressed = false
end
if not controllers.VM.On then
return nil
end
if not currentGun or not data then
return nil
end
if self.Ammo.Mag == 0 then
return nil
end
task.spawn(function()
return self:CreateTracer()
end)
if not suppressed then
self:CreateFlashVFX()
currentGun.Trigger.Fire:Play()
end
self:CalculateRecoil()
self.Ammo.Mag -= 1
self:UpdateUI()
end,
FullAuto = function(self, suppressed)
if suppressed == nil then
suppressed = false
end
if not currentGun or not data then
return nil
end
if self.Ammo.Mag == 0 then
return nil
end
while state.M1Down do
self:CreateFireFX(suppressed)
task.wait(60 / data.firerate)
end
state.Firing = false
end,
Fire = function(self, suppressed)
if suppressed == nil then
suppressed = false
end
if not controllers.VM.On then
return nil
end
if not currentGun or not data then
return nil
end
if self.Ammo.Mag == 0 then
return nil
end
if state.Firing then
return nil
end
state.Firing = true
local _exp = self:GetFiremode()
repeat
if _exp == "auto" then
task.spawn(function()
return self:FullAuto()
end)
break
end
if _exp == "burst" then
task.spawn(function()
return self:Burst()
end)
break
end
if _exp == "semi" then
self:CreateFireFX(suppressed)
task.wait(60 / data.firerate)
state.Firing = false
break
end
error(Exception.new("Unhandled fire mode: " .. self:GetFiremode()))
until true
end,
I’m sure this is quite the simple issue to fix and I’m just overthinking it but I’d like to save the headache because I’ve been working on this specific issue for like an hour lol