Hello, I have ran into a roadblock when dealing with handlers and metatables.
Here is an example:
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local GearLocal = {}
GearLocal.__index = GearLocal
function GearLocal:FindControlHit(x, y)
print(x, y)
if x == nil and y == nil then return end
if x == nil and y ~= nil then x = 0 end
if x ~= nil and y == nil then y = 0 end
local length = 500
local unitRay = self.Camera:ScreenPointToRay(x, y)
local ray = Ray.new(unitRay.Origin, unitRay.Direction * length)
local part, pos = workspace:FindPartOnRayWithIgnoreList(ray,{self.Player.Character})
return part, pos
end
function GearLocal:BindBaseHandlers()
local updateSelectedObjectConn = RunService.Heartbeat:connect(function()
if self.LastInputPosition == nil then return end
self.LastSelectedPart = self.SelectedPart
local x = self.LastInputPosition.X
local y = self.LastInputPosition.Y
self.SelectedPart = self:FindControlHit(x, y)
print(self.SelectedPart)
end)
local onInputMove = UserInputService.InputChanged:connect(function(input)
self.LastInputPosition = input.Position
print("hi")
end)
table.insert(self.Handlers, onInputMove)
table.insert(self.Handlers, updateSelectedObjectConn)
end
function GearLocal.new(tool)
local newGearLocal = {}
setmetatable(newGearLocal, GearLocal)
newGearLocal.Tool = tool
newGearLocal.Player = game.Players.LocalPlayer
newGearLocal.Camera = game.Workspace.CurrentCamera
newGearLocal.LastInputPosition = nil
newGearLocal.SelectedPart = nil
newGearLocal.LastSelectedPart = nil
newGearLocal.Handlers = {}
newGearLocal.Tool.Equipped:connect(function()
newGearLocal:BindBaseHandlers()
end)
newGearLocal.Tool.Unequipped:connect(function()
for _,v in pairs(newGearLocal.Handlers) do
v:Disconnect()
end
newGearLocal.Handlers = {}
end)
return newGearLocal
end
return GearLocal
This runs the error of the following:
It seems as if the metatable no longer exists when “newGearLocal” is passed under an event handler. How can I accomplish to fix this?
i’m guessing there is more to your code, but one reason (i can think of rn) you could be getting that error is because you don’t have an __index metamethod anywhere. Maybe try adding GearLocal.__index = GearLocal
Another instance where metamethods are not saved is when tables are passed to Remote Events/Functions or Bindable Events/Functions; since this is an event handler, this may be a similar issue.
I know what you are doing with this now; rawget gets the indexed item without calling __index which will end up causing a recursive firing if this was not the case.
But on topic, I have tried your method and it still dose not work.
There are also other portions of the script which act the same way; for instance, within “BindBaseHandlers” when it is called without error, the line “self.SelectedPart = self:FindControlHit(x, y)” errors as “FindControlHit” cannot be indexed for some reason
hmm…, i can’t seem to replicate the issue, when copy and pasting your code into a module script and calling GearLocal.new with a tool, nothing errors, and everything seems to work as expected (as far as i know). Solely from your code i can’t see anything that could cause the error you are receiving, So perhaps something else is at play? Does this only happen with the event? is there any specific way you are calling the function?
Also, just as heads up, although this is likely not causing the problem you are having, connect is deprecated, so you might want to use Connect instead.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local LocalGear = require(ReplicatedStorage.LocalGearObjects:WaitForChild("PickaxeLocal"))
--Pickaxe calls GearLocal.new()
local gearLocal = LocalGear.new(script.Parent)
AHA
Finally solved it!!!
There was nothing wrong with the GearLocal module,
There was a problem with another module which was so post to inherit the GearLocal Module
I forgot to connect the two with the following:
setmetatable(Pickaxe, GearLocal)`
This explains why the methods were able to be called outside of the event handler as when the Pickaxe called “GearLocal.new()”, there was a direct ability to call it; however, when it was inside of a event handler, it could not directly be called. This is my guess to what has happened. This may have to do with variable hierarchy → EG Global vars v.s. Local vars.