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))
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)
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
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.
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
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
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.
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))