I’m making a gun and each time the mouse clicks, it calls a function. Let’s say I make a bullet using Instance.new(). If the bullet function was called again, would I never be able to change anything about the old bullet?
You can just return the old bullet in the function
local function createBullet()
local bullet = Instance.new()
return bullet
end
local newBullet = createBullet() --this is the bullet that was created
For scenarios like these, you generally have two options, one of which is easier but (typically) less performant.
For the easier and less performant option, you can perform all of your calculations/logic for each individual bullet in a new thread (thus performing calculations separate from the main thread that instantiated the bullet). This can be done in a variety of ways, but this is what I generally do:
local runSvc = game:GetService'RunService';
local function fireBullet()
local bullet_id: string; --generate a bullet id. the id itself does not matter so long as it differs from all other bullets
--create a bullet
runSvc:BindToRenderStep(bullet_id, 0, function() --consider changing renderpriority for a real game scenario, 0 is just a placeholder
local hit: boolean;
--move the bullet and determine whether the bullet hit something from a raycast performed each frame
if hit then
runSvc:UnbindFromRenderStep(bullet_id);
--deal damage or something and destroy the bullet
end
end);
end
The more conservative option involves combining all these separate threads into one central calculative thread for all bullets. This is generally more performant because we aren’t creating remotely as many threads in most cases, but may introduce some complications to more complex logistics systems:
local runSvc = game:GetService'RunService';
local bullets = {}; --store bullets and all their metadata (lifetime, current distance travelled, damage, or whatever you deem necessary)
runSvc:BindToRenderStep('bullet_handler', 0, function()
for bullet, metadata in bullets do
local hit: boolean;
--perform calculations/logistics for each bullet in the bullets array
if hit then
bullets[bullet] = nil; --remove the bullet that made contact from the array so the handler no longer performs calculations for it
--deal damage or something and destroy the bullet
end
end
end);
local function fireBullet()
local bullet: Instance; --create a bullet
bullets[bullet] = {}; --array here represents the new bullet's metadata
end