Is it possible to create new functions in an "Instance.new()"?

I’m not sure if this is possible but I have found code with a similar purpose using setmetatable

local Players = setmetatable({ A = "This is a custom property!" }, {__index = game:GetService("Players")})

print(Players.LocalPlayer) -- return LocalPlayer
print(Players.A) -- return custom property value

Is it possible to do something similar for this?

local frame = Instance.new('Frame')

function frame:ChangeColor(newcolor)
    self.BackgroundColor3 = newcolor
end

frame:ChangeColor(Color3.new(1, 1, 1))
6 Likes

Wdym new functions? Is it like

local function name() end

3 Likes
local TS = game:GetService("TweenService")

local function New(name)
	local Object = Instance.new(name)
	local Extended = {}

	function Extended:ChangeName(name)
		self.Name = name
	end
	
	function Extended:Workspace()
		self.Parent = workspace
	end
	
	function Extended:TweenProperty(property, new, t, style : Enum.EasingStyle, direction: Enum.EasingDirection)
		local Information = {
			[property] = new
		}
		local TI = TweenInfo.new(t, style, direction)
		local Tween = TS:Create(self, TI, Information)
		Tween:Play()
		return Tween
	end

	setmetatable(Extended, {__index = Object})

	return Extended
end


local Object = New("Part")
Object:Workspace()
task.wait(2)
Object:TweenProperty("Position", Vector3.new(0, 100, 0), 2, Enum.EasingStyle.Sine, Enum.EasingDirection.Out)

(This does not work after further testing)

5 Likes

After further testing It doesn’t seem to 100% work completely. Still testing it, will update further

2 Likes
function CustomIntance(instance, custom_properties)
	return setmetatable({} , {
		__index = function(_,i)
			if custom_properties[i] then return custom_properties[i] end
			return instance[i]
		end,
		__newindex = function(_,i,v)
			instance[i] = v
		end,
		__call = function()
			return instance
		end
	})
end
local properties = {
	ID = '78789a7dadajnda3c'
}
function properties:ChangeColor(newcolor)
	self.BackgroundColor3 = newcolor
end

local frame = CustomIntance(Instance.new('Frame'), properties)

print(frame.ID) -- 78789a7dadajndac

frame.BackgroundColor3 = Color3.new(1, 0, 0)
print(frame.BackgroundColor3) -- 1, 0, 0

frame:ChangeColor(Color3.new(1, 1, 1))
print(frame.BackgroundColor3) -- 1, 1, 1

The only drawback to this is that you have to call it as a function to get the value of the instance; otherwise it will just return a table

local frame = CustomIntance(Instance.new('Frame'))

print(typeof(frame)) -- return table
print(typeof(frame())) -- return instance
3 Likes

Yeah. I was messing around with it, and it seems you cannot parent it to anything. Looks like you break the object once doing this. Since you more than likely break its current __index metamethod which probably allows it to be parented.

1 Like

local wrappercache = setmetatable({}, {__mode = "k"})

wrap = function(real, functions)

	for w,r in next,wrappercache do
		if r == real then
			return w
		end
	end

	if type(real) == "userdata" then
		local fake = newproxy(true)
		local meta = getmetatable(fake)
		
		meta.__index = function(s,k)

			if table.find(functions, k) then
				return functions[k]
			end
			return wrap(real[k])
		end
		
		meta.__newindex = function(s,k,v)
			real[k] = v
		end
		
		meta.__tostring = function(s)
			return tostring(real)
		end
		
		wrappercache[fake] = real
		return fake
		
	elseif type(real) == "function" then
		local fake = function(...)
			local args = unwrap{...}
			local results = wrap{real(unpack(args))}
			return unpack(results)
		end
		wrappercache[fake] = real
		return fake
		
	elseif type(real) == "table" then
		local fake = {}
		for k,v in next,real do
			fake[k] = wrap(v)
		end
		return fake
		
	else
		return real
	end
end
	
unwrap = function(wrapped)
	if type(wrapped) == "table" then
		local real = {}
		for k,v in next,wrapped do
			real[k] = unwrap(v)
		end
		return real
	else
		local real = wrappercache[wrapped]
		if real == nil then
			return wrapped
		end
		return real
	end
end

Using these functions you could

WrappedPart = wrap(workspace.Part, {Hello=function() print(“hello”) end}

WrappedPart.Hello() -- prints: hello

I modified the code from this post:

This post will help you understand better

1 Like
function CustomIntance(instance, custom_properties)
	return setmetatable({} , {
		__index = function(_,i)
			if custom_properties[i] then return custom_properties[i] end
			return instance[i]
		end,
		__newindex = function(_,i,v)
			instance[i] = v
		end
	})
end

local properties = {
	ID = '78789a7dadajndac'
}
function properties:ChangeColor(newcolor)
	self.BackgroundColor3 = newcolor
end

local frame = CustomIntance(Instance.new('Frame'), properties)

print(frame.ID) -- 78789a7dadajndac

frame.BackgroundColor3 = Color3.new(1, 0, 0)
print(frame.BackgroundColor3) -- 1, 0, 0

frame:ChangeColor(Color3.new(1, 1, 1))
print(frame.BackgroundColor3) -- 1, 1, 1

I had already done something similar, the only problem now is this:

local frame = CustomIntance(Instance.new('Frame'))
local newFrame = Instance.new('Frame')
newFrame.Parent = frame -- Error: "Instance expected, got userdata"
1 Like

For the CustomInstance function maybe add a variable called .real which will return the pure object and then for the code do newFrame.Parent = frame.real

1 Like
function CustomIntance(instance, custom_properties)
	return setmetatable({} , {
		__index = function(_,i)
			if custom_properties[i] then return custom_properties[i] elseif i == “real” then return instance end 
			return instance[i]
		end,
		__newindex = function(_,i,v)
			instance[i] = v
		end
	})
end

So if you want to use the pure real object use instance.real, tell me if this works.

1 Like

You’re better off just storing the instance as a class with a property for the object. There are way too many edge cases like these to properly handle instance-wrapping, and even then, extending functionality directly like this will only lead to a more confusing codebase.

local Frame = {}
Frame.__index = Frame

function Frame.new(ID)
	local self = setmetatable({}, Frame)
	
	self.Object = Instance.new("Frame")
	self.ID = ID
	
	return self
end

function Frame:ChangeColor(NewColor)
	self.Object.BackgroundColor3 = NewColor
end

local newFrame = Frame.new("123")
newFrame.Object.Parent = workspace
print(newFrame.ID)
newFrame:ChangeColor(Color3.fromRGB(255, 255, 255))

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.