while true do
if firing then
muzzleFlash:Emit(1)
unit:damage(nearestZombie,unitStats.Damage.Value)
muzzleSound.TimePosition = 0
muzzleSound.Playing = true
wait(1/unitStats.FireRate.Value)
end
wait(0.01)
end
The way the code works is it is inside the main unit behavior script. The RunService.Heartbeat event is connected to the main function which handles most stuff, but it also figures out if the unit should be firing.
I could not find a way to make the script “skip” some heartbeat events in order to maintain a set firerate. So my idea was to have an external firing value and update it. Then the other loop (the one I posted) checks to see if it is firing. All of the stuff inside the ‘if firing’ statement aside from the wait() is fine.
The system works fine but I am wondering if there is any better/smoother way of achieving this behavior? To me the whole loop just screams bad coding because while true do loops are a pretty beginner level tactic.
You can try to use “Aling Orientation” as a physic value, instead of a script doing the rotation to the zombie position, add it to the HumanoidRootPart and experiment with it.
Thank you, I will actually look into this, as I used to have a script do the movement too until that caused issues with clipping and I wasn’t about to write a collisions solver. So i moved that to AlignPosition, moving orientation to physics based as well might be good.
Edit: I was doing some reading on the forums and I found a post talking about optimization, CFrames are very expensive to set so moving to AlignOrientation would remove a lot of lag (each unit sets its CFrame 1-3 times per frame at max)
Yeah, some physics saves a lot of lag and make some scripts functions smoother. It’s a really good choice to see at the game physics limits, so you can use them instead of script functions and improve new ideas about future projects.
You could go on a different approach with the syntax using a continue operator.
while true do
if not firing then
task.wait()
continue
end
muzzleFlash:Emit(1)
unit:damage(nearestZombie,unitStats.Damage.Value)
muzzleSound.TimePosition = 0
muzzleSound.Playing = true
task.wait(1/unitStats.FireRate.Value)
end
I’d rather not use polling as that is a practice which is looked down upon, but I have recently found that .Heartbeat passes along the time delta, which I can use to make accurate fire rates. If anyone else has a better solution though I am up for that.