For some reason when I try to create a unit in my OOP module its not inheriting the properties from the base class (Unit).
I’m creating it like this:
local subClass
local unitModule = unitType.Name
if script.Unit:FindFirstChild(unitModule) then
subClass = require(script.Unit[unitModule])
end
local unitObject = subClass.new(unitType, playerTeam, unitColor)
Then it will go into my warden subClass:
-- MODULE
local Warden = setmetatable({}, Unit)
----------------------------
Warden.__index = Warden
function Warden.new(unitType, unitTeam, unitColor)
local self = setmetatable(Unit.new(), Warden)
self:init()
return self
Then it should call the baseclass to create the unit and inherit the created unit.
-- MODULE
local Unit = {}
----------------------------
Unit.__index = Unit
Unit.unitTypes = {
prefabs:WaitForChild("PulseCannon"),
prefabs:WaitForChild("Warden"),
prefabs:WaitForChild("Tower"),
}
function Unit.new(unitType, unitTeam, unitColor)
local self = setmetatable({}, Unit)
self.UnitType = unitType
self.UnitTeam = unitTeam
self.UnitColor = unitColor
self.UnitObject = self:initializeUnitObject()
self.Alerted = false
self._Janitor = Janitor.new()
self._Janitor:Add(self.UnitObject)
self:OnDestroy()
return self
But for some reason when I use a function from the base class like Unit:Alert() inside a Sub-Class like warden (like this Warden:Alert()) it will go into the unit module and call it, but when it tried to use Properties from the baseclass, it says it does not exist. I understand this is because I am passing the Warden as self and not the Unit, but it should still inherit the properties right?
The function Warden.new calls Unit.new, which creates a new table with the __index metamethod set to Unit. Then, the warden function actually overwrites the __index metamethod, setting it to the Warden class.
Instead, the Warden class itself should inherit from the Unit class, and the Unit.new function would just be overwriten.
Example:
-- unit.lua
local unit = {}
unit.__index = unit
function unit.new()
return setmetatable({},unit)
end
-- warden.lua
local warden = unit.new() -- warden inherits from unit
warden.__index = warden
function warden.new() -- overwrite the .new function
return setmetatable({},warden) -- create a completely new table
end
Is initializeUnitObject actually returning anything?
Also shouldn’t you be passing unitType, unitTeam, unitColor to Unit.new as well? ie setmetatable(Unit.new(unitType, unitTeam, unitColor), Warden). I’m wondering if initializeUnitObject is returning early or returning nil in the case of those 3 args not being passed.
That seems kinda messed up because then you are calling unit.new() on load. Would think that doing what I did was correct as the constructor itself would make a new object of the base class, then overwrites its metatable.
UPDATE: The issue ended up being incredibly stupid and I lost my entire day to this but…
While the code is making a new warden, the table that encapsulates that data doesn’t actually have a name. I’m referring to it as self usually. What’s wrong however, is that I’m calling Warden:Alert() instead of self:Alert() I was passing the module table which holds the functions, NOT the table holding the properties. I feel so incredibly stupid. I can’t believe how I overlooked what I was doing especially since I iterated over it many times. I spent over 6 hours on this.
Thanks to those who replied, I appreciated your input considering I usually get ignored or insulted when asking for code help on the internet.