Hello so before I always used to make stuff in FD but now im planning to create an FE game (just a small project) and I was wondering if someone could explain remoteevents in high detail easy for a beginner to understand, i have already checked the wiki regarding remote events but i didn't fully understand.
I'd also like an answer to these questions besides explaning: 1. where do i put the Server script that make remote events work? 2. how can I make remote events that need certain information to work (for example: Body's CFrame, Player's Name, CFrame of the mouse so it would be :FireServer(HumanoidRootPart.CFrame, plr.Name, mouse.hit.p) and how would i make the server script with that information?
Thank you very much for helping!
If the wiki page didn't help you, then here is a "quick" explanation of how RemoteEvents and Functions work.
So basically, with FE, a LocalScript isn't allowed to change any instances that the server replicates, like things in the workspace. If you try, then other players won't see that change, but you will, which will cause confusion. [However, that can be put to good use, for example, if you want only one player to see something, or be able to go through a door, as seen in Egg Hunt 2018, but that's another story.]
Also, a regular [server] script can't change stuff in a PlayerGui with FE. If you try that, it will work in studio, but not in game
So how would you allow a LocalScript to change the baseplate color from grey to red? Well, you can't do it directly from a LocalScript, otherwise, only the player will see it, and nobody else will. The answer to that is a remote event,
Without Remote Events:
But using Remote Events/functions
As for one of your questions, it is recommended to put server scripts in the ServerScriptService, unless they are meant to be parented to a brick or something. Server Scripts only run in the workspace or ServerScriptService.
And typically, put RemoteEvents and functions in ReplicatedStorage.
Here is an example.
Make a RemoteEvent in the ReplicatedStorage named BaseplateChanger
LocalScript
local remote = game:GetService("ReplicatedStorage"):WaitForChild("BaseplateChanger") remote:FireServer() -- sends signal to RemoteEvent wait(5) print("Scripting is fun") -- prints 5 seconds later. It doesn't wait for the function to finish.
Script in ServerScriptService
local remote = game:GetService("ReplicatedStorage"):WaitForChild("BaseplateChanger") remote.OnServerEvent:Connect(function(player) -- Player parameter workspace.Baseplate.BrickColor = BrickColor.new("Bright red") wait(3) end)
Make a RemoteFunction in the ReplicatedStorage named BaseplateChanger
LocalScript
local remote = game:GetService("ReplicatedStorage"):WaitForChild("BaseplateChanger") remote:FireServer() -- sends signal to RemoteEvent wait(5) print("Scripting is fun") -- prints 8 seconds later, since it waits for the function to finish
Script in ServerScriptService
local remote = game:GetService("ReplicatedStorage"):WaitForChild("BaseplateChanger") remote.OnServerInvoke = function(player) -- Player parameter workspace.Baseplate.BrickColor = BrickColor.new("Bright red") wait(3) end
OnServerInvoke is a callback, so you write the function differently, and InvokeServer is a YieldFunction; it waits for the function to finish, so it yields (waits). Also, only one function can be connected to that callback.
That was a simple use of remote events and functions. Obviously, you're not gonna use them to make the baseplate red, but let's talk about that "player" parameter you see on line 4 of the script. The first parameter is the player who fired that event or invoked the function. All other arguments come next. remember that, or you might get a function that talks about a "userdata value" and be very confused.
That was server to client communication. What about the other way around?
Like I said before, the server can't access the playergui, so the server needs to send a signal to the client
LocalScript (PlayerGui (StarterGui) > ScreenGui > TextLabel > LocalScript)
local remote = game:GetService("ReplicatedStorage"):WaitForChild("BaseplateChanger") remote.OnClientEvent:Connect(function() script.Parent.Text = "I like to script" wait(3) end)
Script in ServerScriptService
local remote = game:GetService("ReplicatedStorage"):WaitForChild("BaseplateChanger") remote:FireClient(player) -- You have to put the player you want to send the signal to. (instance Player) -- or you can do remote:FireAllClients() -- to send signal to all players. wait(5) print("done") -- prints 5 seconds later
LocalScript
local remote = game:GetService("ReplicatedStorage"):WaitForChild("BaseplateChanger") remote.OnClientInvoke = function() script.Parent.Text = "I like to script" wait(3) end)
Script in ServerScriptService
local remote = game:GetService("ReplicatedStorage"):WaitForChild("BaseplateChanger") remote:InvokeClient(player) -- You have to put the player you want to send the signal to. (instance Player) -- There is no such thing as "InvokeAllClients" by the way. wait(5) print("done") -- prints 8 seconds later