I’m looking to create some custom functions/methods for certain instances (such as player:AwardWin() and things like that). How would I go about doing this?
I’ve tried looking it up but I found some methods involving metatables and __index which I don’t understand at all.
I am okay with having to require the module in each script, but I just don’t understand how I would go about creating those custom methods for instances.
I have some knowledge with using ModuleScripts such as creating functions within the module, but I don’t understand much more than that.
We can do this by using metatables. Metatables allow us to override certain operations on tables, the most common ones being __index (called every time something tries to get an index in the table that does not exist) and __newindex (called every time something tries to set a value to an index in the table that does not exist).
local Proxy = {}
function Proxy:AwardWin()
print(self, " has won!")
end
function wrapInstance(object)
local metaTable = {
__index = function(self, index)
if Proxy[index] then
return Proxy[index]
end
return object[index]
end
__newindex = function(self, index, value)
object[index] = value
end
}
return setmetatable({_object = object}, metaTable)
end
We can implement this into a module by simply making the module return the wrapper function.
setmetatable will return the table that it set the metatable on, so it’s just a more concise way of saying
local object2 = {_object = object}
setmetatable(object2, metaTable)
return object2
Don’t return Proxy, that’s not the right thing. You’d be returning the same table every time you called wrapInstance.
A metatable is just a container for functions that will be run when a table is indexed, or called, or added or subtracted or multiplied with etc.
If you wanted to make doing, for example, AllPlayers.Health = 50, then you’d need a table with a metatable, and the metatable’s __newindex is a function that finds every player and sets their Humanoids’ health to something.
local AllHumanoids = {}
local metatable = {}
metatable.__newindex = function(tbl, key, value)
for _,v in ipairs(get all humanoids in the game here, not writing that myself) do
v[key] = value -- if you did AllHumanoids.Health = 40, then this would be "v.Health = 40"
end
end
setmetatable(AllHumanoids, metatable)
AllHumanoids.WalkSpeed = 50
print(AllHumanoids.WalkSpeed) -- prints nil, because it was never set, the function didn't rawset(tbl, key, value)