Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

Passing custom objects between server side and client side with remote events?

Hi all, and Merry Christmas everyone. I'm finally having my first stab at doing some Object Oriented Programming in roblox and have come across a problem when passing objects as arguments into remote events.

The below code shows an example set up.

I have defined a car class with properties position and driver, and created methods TurnLeft and TurnRight. I then instantiate the class in a server script and attempt to pass this object to client side using a remote event.

--module script called Car in game.ReplicatedStorage

--Car Class

Car = {}
Car.__index = Car



function Car.new(position, driver)
    local newcar = {}
    setmetatable(newcar, Car)
	
	-- Define properties position and driver
    newcar.Position = position
    newcar.Driver = driver

    return newcar
end


function Car:TurnLeft()
	--Turn left code
	print("turning left")
end

function Car:TurnRight()
   --Turn right code
	print("turning right")
end

return Car

.

--server script in workspace

Car = require(game.ReplicatedStorage.Car)

newcar = Car.new(Vector3.new(0,10,0),workspace:WaitForChild("123marble")) -- Instantiation

-- Create remote event
local connectButtonsEvent= Instance.new("RemoteEvent")
connectButtonsEvent.Parent = game.ReplicatedStorage
connectButtonsEvent.Name = "connectButtonsEvent"

-- fire client with argument newcar
connectButtonsEvent:FireClient(game.Players["123marble"],newcar)


.

--local script in StarterPlayerScripts

local connectButtonsEvent = game.ReplicatedStorage:WaitForChild("connectButtonsEvent")

function connectButtons(newcar)
	-- printing properties and then calling method TurnLeft
	print(newcar)
	print(newcar.Driver)
	newcar:TurnLeft()
end

connectButtonsEvent.OnClientEvent:Connect(connectButtons)

The resulting output from the execution of the print statements in the local scipt is this

table: 000001DAD3DE4B00
123marble
12:25:27.535 - Players.123marble.PlayerScripts.LocalScript:6: attempt to call method 'TurnLeft' (a nil value)
12:25:27.536 - Stack Begin
12:25:27.536 - Script 'Players.123marble.PlayerScripts.LocalScript', Line 6
12:25:27.537 - Stack End

It can be seen above that the program is able to print the object, and print a property of the object, but cannot call the method TurnLeft. When calling the method TurnLeft I get error nil as if it does not exist.

Question: Why is it that I am able to access the properties, but not the methods of an object when transferring it between server side and client side using a remote event, and how can I access a custom object on server side and client side with its methods in roblox?

Thank you in advance for any replies!

2 comments

1

When you pass tables through the network, a copy is sent, not the actual thing, and the metatable is stripped from the copy, so if you applied metamethod it won't work properly.

0

Thank you. I just applied the setmetatable metamethod again and now everything works perfectly!

1 answer

Although I don't understand all those _index and setmetatable() stuff, I'll do my best! Heh...

function Car:TurnLeft()
    --Turn left code
    print("turning left")
end

function Car:TurnRight()
   --Turn right code
    print("turning right")
end

Something in those lines in the module goes wrong, I assume it doesn't define it correctly? Judging by your output:

table: 000001DAD3DE4B00 123marble 12:25:27.535 - Players.123marble.PlayerScripts.LocalScript:6: attempt to call method 'TurnLeft' (a nil value) 12:25:27.536 - Stack Begin 12:25:27.536 - Script 'Players.123marble.PlayerScripts.LocalScript', Line 6 12:25:27.537 - Stack End


"12:25:27.535 - Players.123marble.PlayerScripts.LocalScript:6: attempt to call method 'TurnLeft' (a nil value)"

Which states that when the localscript calls "TurnLeft", "TurnLeft" doesn't exist (nil) when it calls it from "newcar".


As a noob(me)-fix, because I don't know how else to do it, you could rewrite the module to be like:

--module script called Car in game.ReplicatedStorage

--Car Class

Car = {}
Car.__index = Car

Car = {
new = function(position, driver)
    local newcar = {}
    setmetatable(newcar, Car)

    -- Define properties position and driver
    newcar.Position = position
    newcar.Driver = driver

    return newcar
end,


TurnLeft = function()
    --Turn left code
    print("turning left")
end,

TurnRight = function()
   --Turn right code
    print("turning right")
end,
}

return Car

Hopefully that helps, if it doesn't, sorry I couldn't!

BUT, luckily, judging by my knowledge, it has NOTHING to do with server-client interactions.

If you're wondering why I have two "Cars = {}" it is so the table is defined in the script, so the script itself and the table functions can use Cars and any functions or tables in it.

This discussion is preserved as it was. New answers, comments, and votes are closed.