It feels buggy because you have a wait() before anything happens when you click, thus there is an unnecessary delay between clicking and the fire() function getting called. To make the gun feel more responsive this wait() should be placed after the if statement has happened.
2 | if cooldown = = false then |
Now, more importantly, you definitely should be using RunService.Heartbeat:Wait() (https://developer.roblox.com/en-us/api-reference/class/RunService) because wait() is only able to delay the script 1/30th of a second while using what I put above allows you to have a delay of half that.
If the script you provided isn't a localscript, it needs to be to use the renderstepped wait. There is no way to keep the script a non-local and have a smaller delay.