I’m trying to destroy a bullet object if it times out or manages to hit something. The problem is that I’m getting an error “attempt to call a nil value” on the line containing the :Destroy() call. I’ve checked the object itself and it still exists, done this by printing one of its values.
The modulescript looks like this:
local bullet = {}
bullet.__index = bullet
function bullet.new(part, velocity)
local self = {
part = part,
velocity = velocity,
lifeTime = 0
}
setmetatable(self, bullet)
return self
end
return bullet
The server script saves all the bullets in a dictionary with the object as a key, that way I can iterate through the dictionary and grab the object to destroy it. (Maybe there’s a better way?)
Server Script:
local bullets = {}
local function moveBullets()
for i, bullet in pairs(bullets) do
-- Check if lifeTime has run out
if bullet.lifeTime >= 120 then
bullet:Destroy()
bullets[bullet] = nil
else
if raycastResult then
bullet:Destroy()
bullets[bullet] = nil
end
bullet.lifeTime = bullet.lifeTime + 1
end
end
end
game.ReplicatedStorage.RemoteEvents.RequestShot.OnServerEvent:Connect(function(plr, cframe, velocity)
local bulletObj = bulletClass.new(bulletPart, velocity)
bullets[bulletObj] = bulletObj
end)
-- Start heartbeat on server startup
local connection = runService.Heartbeat:Connect(moveBullets)
I removed some code from the example that only updates and checks on the objects values but you should get a hang of what the code is doing still.
Why can’t it run :Destroy() on the bullet objects?
Now this might not be the best solution, but after a said amount of time, or before you destroy it, parent the bullet into ReplicatedFirst, and add a script in replicated first like this:
for i, Objects in pairs(script.Parent:GetChildren()) do
if Objects.Name == "Bullet" then -- Change to the bullet name
Objects:Destroy()
else
return
end)
Yeah, you could then also use the __metatable metamethod and cause it to error to lock the metatable which I think roblox does, that way it isn’t modifiable. I don’t think there aren’t any other destructors aside from just stopping every reference to the table, though I might be wrong.
I found a way around it this time, I added the properties as attributes to the part and skipped even need to use OOP this time. I’m used to C++ style of memory management so lua’s metatables and the garbage collection is a bit foreign to me. Since it’s only a part I can also use the debris system roblox has