Function which when called on a BasePart or Model runs code within it / on it

I come from a purely object oriented background, with my Lua experience mainly from Garry’s Mod where “entities” are tables which you can add functions to.
What I want to do is to essentially be able to say workspace.Light:Toggle()
Instead I have a ModuleScript called InteractionManager which has a function ToggleLight, where I pass in the light switch as an argument, which seems far more awkward and less abstracted as I have to import this into any script where I want to toggle a light switch.

Unfortunately there is no way to do this natively, you would have to use an object wrapper, or you can use a ModuleScript. If you’re interested in an object wrapper with a relatively seamless implementation (when I say seamless I mean have it automatically pass the instance to methods instead of having to do lightController.SomeInstanceFunction(lightInstance, value), I touched on it a little bit here, it would look something like this:

local lightController = {}

function lightController.new(light --[[light is an instance, probably some type of light]])
    local newLightController = {}
    newLightController.On = false
    function newLightController:Toggle()
        newLightController.On = not newLightController.On
        light.Brightness = newLightController.On and 15 or 0
    end
    local metatable = {
        __index = function(tbl,key)
            if type(light[key]) == 'function' then -- this first check handles methods/functions that are inside of the instance itself
					return function(tbl, ...)
						return light[key](light,...) -- this calls the instance's method
					end
				else
					return light[key] -- this returns the light instance's property
				end
            end
        end
        __newindex = function(tbl,key,value)
            if light[key] ~= nil then -- we have to explicitly check if the value is nil, otherwise a value might be false and it will incorrectly "flag" (for lack of a better word)
                light[key] = value -- assign the property
            end
        end
    }
    return setmetatable(newLightController, metatable)
end

return lightController

I haven’t tested this out myself but it should work. Let me know if there are any issues or if you have any questions.

1 Like