Creating GUI's on the fly with metatables issue

I haven’t quite seen anyone try this, So looking for useful resources on how to accomplish/fix this are scarce.

Tl;dr, I’m trying to create a module that creates GUI components on the fly. I have an idea of how it should work, I’m just trying to piece things together. This is what I currently have.

local GUICreator = {}

function GUICreator.new(player,Type,Parent)
	local self = setmetatable({}, GUICreator)
	self.player = player
	local frameData = {
		frame = function(Type,Parent) Instance.new(Type,Parent) end
	}
	return self
end


function GUICreator:Build(Type,Parent)
	self.frameData.frame(Type,Parent)
end



return GUICreator

If I have this setup correctly, I should be able to just call the build function wherever I need it. In another script that handles the GUI building (which is why im making this in the first place) I’m trying to do this.

local p = game.StarterGui.Backpack.BackpackUI.MainFrame
GUIModule:Build("Frame",p)

This is the module in the most basic form, doing ^ will create a frame and place it at the specified parent. On line 14 I get this error

Attempt to index nil with 'frame'

RobloxStudioBeta_ZZ8jxAesFY

For all I know, I could have this setup completely wrong, this is my first crack at messing with metatables so hopefully I started this off a little right.

Do self.frameData = frameData to put it into the object properties table.

Oh wow, didn’t notice that. Even afterwards the issue is still ther though :\

So Its because I’m never calling GUIModule.new() anywhere hahaha. I’m not sure what the proper was is though because even when I predefine the variables, i still get an error. My error is ‘Attempt to call a nil value’

RobloxStudioBeta_3Wk1IVNApF

Ideally, I wouldnt like to have these predefined.I’m trying to achieve what i had mentioned above.

Does it say where the nil value error is coming from?

Is it from the self.frameData.frame in gui:Build()?
If it is, your problem is you aren’t making the module an object, so it isn’t actually associating :Build() with your GUIModule.

local GUICreator = {}
GUICreator.__index = GUICreator

-- ... rest of code

Also, you shouldn’t use the parent parameter of Instance.new() and you aren’t storing this object anywhere!

function GUICreator.new(player,Type,Parent)
	local self = setmetatable({}, GUICreator)
	self.player = player
	self.frameData = {
		frame = function(Type,Parent)
			self._object = Instance.new(Type) --Parenting straight out of Instance.new can cause performance issues.
			self._object.Parent = Parent
		end
	}
	return self
end

welp, thats where it was. I forgot to index the object. Thank you for reminding me, that fixed the issue.

1 Like