How to get a metatable with an ID system?

How would I go about getting the metatable of a model. I currently have a script that instantiates a new object with a model passed as the argument. I’d like to know how I could make a function that could take in possible information about the metatable, i.e object ID, and will return the metatable corresponding to that ID. In this example the function would need a model. I could just send the information about the objects through events, bindable events, etc, but I want to find a way to do this. How could I use getmetatable properly with this? It’d make sense that the use of getmetatable would be for when you don’t have a reference to said metatable.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Maid = require(ReplicatedStorage:WaitForChild("Maid"))

local WeepingAngle = {}
WeepingAngle.__index = WeepingAngle


function WeepingAngle.new(angle)
	local self = setmetatable({}, WeepingAngle)
	self.__maid = Maid.new()
	self.__selfCleanup = self.__maid:GiveTask(self)
	
	self.Model = angle
	
	return self
end

function WeepingAngle.GetMetatableFromModel(model)
	return -- The model's metatable
end

function WeepingAngle:Init()
	warn(self.Model.Name.." has been initalised.")
end


function WeepingAngle:Destroy()
	self.__selfCleanup:DoCleaning()
	self.__maid:Destroy()
end


return WeepingAngle
1 Like

Here’s a better example of what I’m trying to achieve

local id = 124
local obj = module.new(id) -- Instantiates

-- Inside of another script
local id = 124
local obj = module.getMetatableWithId(id) -- Takes in an ID and returns the object

I understand the principle here, however I’m having issues actually getting this to work. I’ve been looking around for methods to retrieve specific metatables associated to a table, but can’t find any.

I tried this test to see what happened when you called getmetatable() on a table with multiple metatables:

local t = {}
local mt1 = {}
mt1.Number = 2
local mt2 = {}
mt2.Number = 3
setmetatable(t,mt1)
setmetatable(t,mt2)

local mt = getmetatable(t)
print(mt.Number)
local mt = getmetatable(t)
print(mt.Number)
local mt = getmetatable(t)
print(mt.Number)
local mt = getmetatable(t)
print(mt.Number)

The result was that every time it printed the value associated to the first metatable associated with the table, and never the second.

My guess is that you’ll need a unique index for every metatable to make this work (maybe the model’s name or a special attribute for each one), and can then use the __index metamethod to retrieve the model associated with the metatable you’re looking for.

Not really sure about any of this, just a hunch really. Good luck!

1 Like

Are you sure you mean metatable and not just want to grab an instance? I think you can just have a table in your module and add any new instances to that table when they are created. You’d then also have to clean this up when instances are destroyed which you can put in the destroy method.

1 Like

It would look something like this:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Maid = require(ReplicatedStorage:WaitForChild("Maid"))

local WeepingAngle = {}
WeepingAngle.__index = WeepingAngle

local instances = {}

function WeepingAngle.new(angle)
	local self = setmetatable({}, WeepingAngle)
	self.__maid = Maid.new()
	self.__selfCleanup = self.__maid:GiveTask(self)
	
    self.Model = angle
	
    instances[angle] = self

	return self
end

function WeepingAngle.GetMetatableFromModel(model)
     -- The model's WeepingAngle instance
	return instances[model]
end

function WeepingAngle:Init()
	warn(self.Model.Name.." has been initalised.")
end


function WeepingAngle:Destroy()
    instances[self.Model] = nil
	self.__selfCleanup:DoCleaning()
	self.__maid:Destroy()
end


return WeepingAngle
2 Likes

Yes, I meant the instance. How haven’t I thought of this. I think I should stop over complicating things. Thanks!

1 Like