I’m making an O.O.P module for my game that essentially handles all the guns. (Since the guns act VERY similar to each-other with slight differences.) I have a “data” variable that holds data from that gun’s specific module. When I try to access a specific value from that module, it says “attempt to index nil with ___”
function GunController.new(tool: Tool)
local weaponData = require(ReplicatedStorage.Gun.Data[tool.Name])
local self = {
tool = tool,
data = weaponData,
equipped = false,
activated = false,
shooting = false,
reloading = false,
ammo = tool:GetAttribute("Ammo"),
reloadingState = tool:GetAttribute("Reloading"),
lastTick = tick(),
connections = {}
}
setmetatable(self, GunController)
self:initialize()
return self
end
Below is the line of code that is having problems.
function GunController:startShooting()
if self.equipped then
if self.ammo == 0 then
-- reload
end
local fireMode = self.data["FIRE_MODE"] -- ERROR
local rateOfFire = self.data["FIRERATE"]
If I try printing self.data in the constructor thread, it outputs all the values as a table like normal. If I try printing the self.data in the :startShooting() function, it prints nil?
local GunController = {}
GunController.__index = GunController
function GunController.new(tool: Tool)
local weaponData = require(ReplicatedStorage.Gun.Data[tool.Name])
local self = {
tool = tool,
data = weaponData,
equipped = false,
activated = false,
shooting = false,
reloadingState = false,
ammo = tool:GetAttribute("Ammo"),
reloading = tool:GetAttribute("Reloading"),
lastTick = tick(),
connections = {}
}
setmetatable(self, GunController)
self:initialize()
return self
end
function GunController:initialize()
table.insert(self.connections, self.tool.Equipped:Connect(function() GunController:equip() end))
table.insert(self.connections, self.tool.Unequipped:Connect(function() GunController:unequip() end))
table.insert(self.connections, self.tool.Activated:Connect(function() GunController:activate() end))
table.insert(self.connections, self.tool.Deactivated:Connect(function() GunController:deactivate() end))
end
function GunController:equip()
if self.equipped then
return
end
self.equipped = true
end
function GunController:unequip()
if not self.equipped then
return
end
self.equipped = false
end
function GunController:activate()
if self.activated then
return
end
self.activated = true
self:startShooting()
end
function GunController:deactivate()
if not self.activated then
return
end
self.activated = false
end
function GunController:startShooting()
if self.equipped then
if self.ammo == 0 then
-- reload
end
local fireMode = self.data["FIRE_MODE"]
local rateOfFire = self.data["FIRERATE"]
if fireMode == "Semi" then
self.shooting = true
print("shot")
task.delay(rateOfFire, function()
self.shooting = false
if self.ammo == 0 then
-- reload
end
end)
elseif fireMode == "Auto" then
task.spawn(function()
self.shooting = true
while self.activated do
if (tick() - self.lastTick) > rateOfFire then
print("shot")
self.lastTick = tick()
else
task.wait()
end
end
self.shooting = false
if self.ammo == 0 then
-- reload
end
end)
end
end
end
return GunController
I’m kinda grasping at straws but, when I started learning OOP, I kept accidently calling the module script to call the function. Did you create the object then call the function on the object and not the modulescript?
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local GunController = require(ReplicatedStorage.Gun.Classes.GunController)
local Controller = GunController.new(script.Parent) -- script.Parent is the tool