generic image
Processing...
  • Games
  • Catalog
  • Develop
  • Robux
  • Search in Players
  • Search in Games
  • Search in Catalog
  • Search in Groups
  • Search in Library
  • Log In
  • Sign Up
  • Games
  • Catalog
  • Develop
  • Robux
   
ROBLOX Forum » Game Creation and Development » Scripters
Home Search
 

Re: Metatable/Wrapper Function Issue

Previous Thread :: Next Thread 
WoolHat is online. WoolHat
Joined: 19 May 2013
Total Posts: 1873
01 Dec 2017 03:19 PM
I'm trying to make a custom Humanoid class. If you're going to tell me that classes/metatables are useless, that's nice; I'd still like to test this out for myself.

Things in this setup work fine, with the exception being: When I call the method :GetChildren(), which then indexes ModuleScript object's table of properties, I get the error saying that ":" was not used, but "." was. I'd like to find out why this error is appearing, and if there's a way to fix it.


local Humanoid = {}

local HumanoidData = {
Name = "Humanoid",
CameraOffset = Vector3.new(0,0,0),

Health = 100,
MaxHealth = 100,
JumpPower = 50,
WalkSpeed = 16,
Jump = false,

TakeDamage = function(self,Damage)
self.Health = self.Health - Damage
end
}

do
local CustomProperties = setmetatable(HumanoidData, {__index=script}) --If property isn't in HumanoidData, look through ModuleScript
Humanoid = setmetatable({},{__index=CustomProperties}) --If property isn't in {}, look through CustomProperties
end

print(Humanoid.Archivable)--Prints the ModuleScript's True archivable value
Humanoid:TakeDamage(5)--Successfully decrements the health by 5
Humanoid:GetChildren()--"Expected ':' not '.' calling member function GetChildren"

return Humanoid
Report Abuse
cntkillme is not online. cntkillme
Joined: 07 Apr 2008
Total Posts: 44956
01 Dec 2017 04:12 PM
The problem is your fake humanoid object is being propogated as the “self” to the real GetChildren method.
So it ends up doing script.GetChildren(fakeHumamoid) and since it isn’t an actual instance Roblox just spits out that error since self isn’t an instance.

To solve this you’d have to do something like
__index = function(self, key)
local value = CustomProperties[key]
if type(value) == “function” then
return function(_, ..,)
return value(realHumanoid, ...)
end
end
end

You should probably have it fallback to the real humanoid instead of script but oh well.
Report Abuse
WoolHat is online. WoolHat
Joined: 19 May 2013
Total Posts: 1873
01 Dec 2017 10:23 PM
I edited it to follow your recommended code, but it still yields the same error. Question before I paste the new code: How would it be able to search the the script object before searching through the table of properties? setmetatable takes only table arguments, as opposed to objects.
Updated code:

local Humanoid = {}

local HumanoidData = {
Name = "Humanoid",

Health = 100,
MaxHealth = 100,
JumpPower = 50,
WalkSpeed = 16,
Jump = false,

TakeDamage = function(self,Damage)
self.Health = self.Health - Damage
end
}

do
local ModuleProperties = setmetatable({ },{__index = script})

Humanoid = setmetatable(HumanoidData,{
__index = function(self, key)
local ModuleProperty = ModuleProperties[key]
if type(ModuleProperty) == "function" then
return function(_,...)
return ModuleProperty(HumanoidData,...)
end
end
end
})
end

print(Humanoid.Archivable)--Prints the ModuleScript's True archivable value
Humanoid:TakeDamage(5)--Successfully decrements the health by 5
Humanoid:GetChildren()--"Expected ':' not '.' calling member function GetChildren"

return Humanoid
Report Abuse
cntkillme is not online. cntkillme
Joined: 07 Apr 2008
Total Posts: 44956
01 Dec 2017 10:30 PM
No you implemented it wrong, you're still passing a FAKE OBJECT to a REAL ROBLOX METHOD.
Read what I put.

If you want to index script first, create an object to force __index to fire then just index the script first (with pcall in the case the member doesn't exist).
Report Abuse
WoolHat is online. WoolHat
Joined: 19 May 2013
Total Posts: 1873
02 Dec 2017 11:25 PM
Did it! Here's my resulting code, for anyone who may take use of it later on. If there are any recommendations/issues you find, I'd like to know so I can try to fix them.

local Humanoid = {}

local HumanoidData = {
Name = "Humanoid",

Health = 100,
MaxHealth = 100,
JumpPower = 50,
WalkSpeed = 16,
Jump = false,

TakeDamage = function(self,Damage)
self.Health = self.Health - Damage
end
}

do
setmetatable(HumanoidData,{ --Checks for properties in the fake humanoid
__index = function(self,key)--Function only runs after HumanoidData turns out to not have any results
error(key.." is not a valid member of Humanoid")
end
})

Humanoid = setmetatable({},{
__index = function(self, key)
local ModulePropertyFound,ModuleProperty = pcall(function()
return script[key]
end)

if ModulePropertyFound or ModulePropertyFound then
if type(ModuleProperty) == "function" then --Check for methods of the fake humanoid
return function(_,...)
return ModuleProperty(script,...) --pass arguments appropriately
end
else
return ModuleProperty
end
else
local HumanoidProperty = HumanoidData[key]
return HumanoidProperty
end
end
})
end

print(Humanoid.Parent)--Prints the ModuleScript's True archivable value
print(Humanoid.Health)
Humanoid:TakeDamage(5)--Successfully decrements the health by 5
print(Humanoid.Health)
print(unpack(Humanoid:GetChildren()))--Prints all children of the modulescript/fake humanoid
print(Humanoid.Jump)
print(Humanoid.yy)

return Humanoid
Report Abuse
Dollar500 is not online. Dollar500
Joined: 12 Jan 2013
Total Posts: 504
02 Dec 2017 11:28 PM
So, what exactly is this for? Humanoids are already part of roblox...
Report Abuse
WoolHat is online. WoolHat
Joined: 19 May 2013
Total Posts: 1873
02 Dec 2017 11:39 PM
Well, the Humanoids are conflicting with me for a certain project I'm working on. So I'm creating my own humanoid, with its own properties.

All this code is in a ModuleScript called "Humanoid", which would go in a character model in place of a regular Humanoid. When the module is required, it returns a table that acts as a Humanoid, with all of the properties that I want it to have.

In the code I put above, the humanoid has explicit properties of Humanoid.Health, Humanoid.Jump. But I can also use function default to the ModuleScript, like Humanoid:GetChildren().

Tl;dr when I need to rewrite every new Humanoid function, I'll give up
Report Abuse
Dollar500 is not online. Dollar500
Joined: 12 Jan 2013
Total Posts: 504
02 Dec 2017 11:41 PM
Makes sense
Report Abuse
gskw is not online. gskw
Joined: 05 Jan 2013
Total Posts: 1364
03 Dec 2017 02:42 AM
You should totally use the BaseLib/LiteLib from a project of Crescent Code whose name can't be posted on Roblox (Norse god). It will help you do this.
Report Abuse
Previous Thread :: Next Thread 
Page 1 of 1
 
 
ROBLOX Forum » Game Creation and Development » Scripters
   
 
   
  • About Us
  • Jobs
  • Blog
  • Parents
  • Help
  • Terms
  • Privacy

©2017 Roblox Corporation. Roblox, the Roblox logo, Robux, Bloxy, and Powering Imagination are among our registered and unregistered trademarks in the U.S. and other countries.



Progress
Starting Roblox...
Connecting to Players...
R R

Roblox is now loading. Get ready to play!

R R

You're moments away from getting into the game!

Click here for help

Check Remember my choice and click Launch Application in the dialog box above to join games faster in the future!

Gameplay sponsored by:
Loading 0% - Starting game...
Get more with Builders Club! Join Builders Club
Choose Your Avatar
I have an account
generic image