Roblox-Spiele sind von Natur aus Multiplayer, sodass alle Spiele grundsätzlich zwischen dem Server und den verbundenen Clients der Spieler kommunizieren. Im einfachsten Fall, während Spieler ihre Charaktere bewegen, werden bestimmte Eigenschaften von Humanoid, wie Zustände, an den Server übermittelt, der diese Informationen an andere verbundene Clients weitergibt.
Remote-Events und Rückrufe ermöglichen es Ihnen, über die Client-Server-Grenze hinweg zu kommunizieren:
- RemoteEvents ermöglichen eine einseitige Kommunikation (eine Anfrage senden und nicht auf eine Antwort warten).
- UnreliableRemoteEvents ermöglichen eine einseitige Kommunikation für Daten, die kontinuierlich verändert werden oder für den Zustand des Spiels nicht kritisch sind. Diese Events tauschen Reihenfolge und Zuverlässigkeit gegen verbesserte Netzwerkleistung.
- RemoteFunctions ermöglichen eine bidirektionale Kommunikation (eine Anfrage senden und warten, bis eine Antwort vom Empfänger empfangen wird).
Im Gegensatz zu bindbaren Events, die eine eingeschränktere Nutzbarkeit haben, sind die Anwendungsfälle für Remote-Events und -Funktionen zu vielfältig, um sie aufzulisten:
- Gameplay - Grundlegendes Gameplay, wie beispielsweise ein Spieler, der das Ende eines Levels erreicht, kann ein Remote-Event erfordern. Ein Client-Skript benachrichtigt den Server, und Server-Skripte setzen die Position des Spielers zurück.
- Serverüberprüfung - Wenn ein Spieler versucht, einen Trank zu trinken, hat er diesen Trank tatsächlich? Um Fairness zu gewährleisten, muss der Server die Quelle der Wahrheit für ein Spiel sein. Ein Client-Skript kann ein Remote-Event verwenden, um den Server zu benachrichtigen, dass der Spieler einen Trank trinkt, und dann können Server-Skripte entscheiden, ob der Spieler diesen Trank tatsächlich hat und ob ihm Vorteile gewährt werden sollen.
- Benutzeroberflächenupdates - Wenn sich der Spielzustand ändert, können Server-Skripte Remote-Events verwenden, um die Clients über Änderungen an Punktzahlen, Zielen usw. zu benachrichtigen.
- In-Game-Marktplatzkäufe - Für ein Beispiel für eine Implementierung, die Remote-Funktionen verwendet, siehe Aufforderung zum Abonnieren von Käufen.
Schnelles Nachschlagewerk
Die folgenden Tabellen dienen als schnelles Nachschlagewerk, wie man RemoteEvents und RemoteFunctions verwendet, um zwischen Client und Server zu kommunizieren.
| Client → Server | |
|---|---|
| Client | RemoteEvent:FireServer(args) |
| Server | RemoteEvent.OnServerEvent:Connect(function(player, args)) |
| Server → Client | |
| Server | RemoteEvent:FireClient(player, args) |
| Client | RemoteEvent.OnClientEvent:Connect(function(args)) |
| Server → Alle Clients | |
| Server | RemoteEvent:FireAllClients(args) |
| Client | RemoteEvent.OnClientEvent:Connect(function(args)) |
Remote-Events
Ein RemoteEvent-Objekt ermöglicht asynchrone, einseitige Kommunikation über die Client-Server-Grenze hinweg, ohne auf eine Antwort zu warten.
Um ein neues RemoteEvent über das Explorer Fenster in Studio zu erstellen:
- Fahren Sie mit der Maus über den Container, in den Sie das RemoteEvent einfügen möchten. Um sowohl Server- als auch Clientzugriff sicherzustellen, muss es sich an einem Ort befinden, an dem beide Seiten es sehen können, wie z.B. ReplicatedStorage, obwohl es in einigen Fällen angemessen ist, es in Workspace oder innerhalb eines Tool zu speichern.
- Klicken Sie auf die ⊕-Schaltfläche, die rechts neben dem Namen des Containers erscheint, und fügen Sie eine RemoteEvent-Instanz ein.
- Benennen Sie die Instanz um, um ihren Zweck zu beschreiben.
Nachdem Sie ein RemoteEvent erstellt haben, kann es die einseitige Kommunikation vom Client zum Server, vom Server zum Client oder vom Server zu allen Clients erleichtern.



Client → Server
Sie können ein LocalScript verwenden, um ein Event auf dem Server auszulösen, indem Sie die Methode FireServer() auf einem RemoteEvent aufrufen. Wenn Sie Argumente an FireServer() übergeben, werden diese an die Ereignisbehandlungsroutine auf dem Server mit bestimmten Einschränkungen übergeben. Beachten Sie, dass der erste Parameter der Ereignisbehandlungsroutine auf dem Server immer das Player-Objekt des Clients ist, der es aufruft, und zusätzliche Parameter folgen.
| Client | RemoteEvent:FireServer(args) |
| Server | RemoteEvent.OnServerEvent:Connect(function(player, args)) |
Das folgende Script verbindet eine Ereignisbehandlungsroutine mit OnServerEvent, die ein neues Part auf dem Server erstellt. Das begleitende LocalScript ruft dann FireServer() auf der RemoteEvent-Instanz mit der gewünschten Color und Position für den Teil auf.
Ereignisverbindung - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- Holen Sie sich eine Referenz zur Remote-Event-Instanz
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onCreatePart(player, partColor, partPosition)
print(player.Name .. " hat das RemoteEvent ausgelöst")
local newPart = Instance.new("Part")
newPart.Color = partColor
newPart.Position = partPosition
newPart.Parent = Workspace
end
-- Funktion mit dem Ereignis verbinden
remoteEvent.OnServerEvent:Connect(onCreatePart)
Ereignisauslösung - LocalScriptlocal ReplicatedStorage = game:GetService("ReplicatedStorage")-- Holen Sie sich eine Referenz zur Remote-Event-Instanzlocal remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")-- Remote-Event auslösen und zusätzliche Argumente übergebenremoteEvent:FireServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))
Server → Client
Sie können ein Script verwenden, um ein Event auf einem Client auszulösen, indem Sie die Methode FireClient() auf einem RemoteEvent aufrufen. Das erste Argument für FireClient() ist das Player-Objekt des Clients, der auf das Event reagieren soll, und zusätzliche Argumente werden mit bestimmten Einschränkungen an den Client übergeben. Beachten Sie, dass die Ereignisbehandlungsroutine das Player-Objekt nicht als erstes Argument enthalten muss, da Sie den Spieler auf dem Client mit Players.LocalPlayer bestimmen können.
| Server | RemoteEvent:FireClient(player, args) |
| Client | RemoteEvent.OnClientEvent:Connect(function(args)) |
Das folgende LocalScript verbindet eine Ereignisbehandlungsroutine mit dem OnClientEvent-Event. Das begleitende Script hört dann auf eingehende Spieler auf den Server und ruft für jeden FireClient() mit beliebigen Daten auf.
Ereignisverbindung - LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Holen Sie sich eine Referenz zur Remote-Event-Instanz
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local player = Players.LocalPlayer
local function onNotifyPlayer(maxPlayers, respawnTime)
print("[Client] Ereignis empfangen von Spieler", player.Name)
print(maxPlayers, respawnTime)
end
-- Funktion mit dem Ereignis verbinden
remoteEvent.OnClientEvent:Connect(onNotifyPlayer)
Ereignisauslösung - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Holen Sie sich eine Referenz zur Remote-Event-Instanz
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Auf eingehende Spieler hören und Remote-Event an jeden dispatchen
local function onPlayerAdded(player)
print("[Server] Ereignis auslösen für Spieler", player.Name)
remoteEvent:FireClient(player, Players.MaxPlayers, Players.RespawnTime)
end
Players.PlayerAdded:Connect(onPlayerAdded)
Server → Alle Clients
Sie können ein Script verwenden, um ein Event bei allen Clients auszulösen, indem Sie die Methode FireAllClients() auf einem RemoteEvent aufrufen. Im Gegensatz zu FireClient(), erfordert die Methode FireAllClients() kein Player-Objekt, da sie das RemoteEvent an alle Clients auslöst.
| Server | RemoteEvent:FireAllClients(args) |
| Client | RemoteEvent.OnClientEvent:Connect(function(args)) |
Das folgende LocalScript verbindet eine Ereignisbehandlungsroutine mit dem OnClientEvent-Event, das die verbleibende Countdown-Zeit ausgibt. Das begleitende Script ruft dann in einer Schleife jede Sekunde FireAllClients() auf, um das RemoteEvent für alle Clients auszulösen.
Ereignisverbindung - LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Holen Sie sich eine Referenz zur Remote-Event-Instanz
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onTimerUpdate(seconds)
print(seconds)
end
-- Funktion mit dem Ereignis verbinden
remoteEvent.OnClientEvent:Connect(onTimerUpdate)
Ereignisauslösung - Scriptlocal ReplicatedStorage = game:GetService("ReplicatedStorage")-- Holen Sie sich eine Referenz zur Remote-Event-Instanzlocal remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")local countdown = 5-- Fire das RemoteEvent jede Sekunde, bis die Zeit abgelaufen istfor timeRemaining = -1, countdown doremoteEvent:FireAllClients(countdown - timeRemaining)task.wait(1)end
Remote Rückrufe
Ein RemoteFunction-Objekt ermöglicht synchronisierte, bidirektionale Kommunikation über die Client-Server-Grenze. Der Absender einer Remote-Funktion wird warten, bis er eine Antwort vom Empfänger erhält.
Um eine neue RemoteFunction über das Explorer Fenster in Studio zu erstellen:
- Fahren Sie mit der Maus über den Container, in den Sie die RemoteFunction einfügen möchten. Um sowohl Server- als auch Clientzugriff sicherzustellen, muss es sich an einem Ort befinden, an dem beide Seiten es sehen können, wie z.B. ReplicatedStorage, obwohl es in einigen Fällen angemessen ist, es in Workspace oder innerhalb eines Tool zu speichern.
- Klicken Sie auf die ⊕-Schaltfläche, die rechts neben dem Namen des Containers erscheint, und fügen Sie eine RemoteFunction-Instanz ein.
- Benennen Sie die Instanz um, um ihren Zweck zu beschreiben.
Nachdem Sie eine RemoteFunction erstellt haben, kann sie die bidirektionale Kommunikation zwischen Client und Server oder zwischen Server und Client erleichtern.


Client → Server → Client
Sie können ein LocalScript verwenden, um eine Funktion auf dem Server aufzurufen, indem Sie die Methode InvokeServer() auf einer RemoteFunction aufrufen. Im Gegensatz zu einem Remote-Event wartet das LocalScript, das die RemoteFunction aufruft, bis der Rückruf zurückkehrt. Die Argumente, die Sie an InvokeServer() übergeben, werden an den OnServerInvoke-Rückruf der RemoteFunction mit bestimmten Einschränkungen übergeben. Beachten Sie, dass, wenn Sie mehrere Rückrufe für die gleiche RemoteFunction definieren, nur die letzte Definition ausgeführt wird.
| Client | RemoteFunction:InvokeServer(args) |
| Server | RemoteFunction.OnServerInvoke = function(player, args) |
Das folgende Script definiert die Rückruffunktion über OnServerInvoke und gibt das angeforderte Part über den return-Wert zurück. Das begleitende LocalScript ruft dann InvokeServer() mit zusätzlichen Argumenten auf, die die angeforderte Teilfarbe und -position definieren.
Rückrufverbindung - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- Holen Sie sich eine Referenz zur Remote-Funktionsinstanz
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Rückruffunktion
local function createPart(player, partColor, partPosition)
print(player.Name .. " hat ein neues Teil angefordert")
local newPart = Instance.new("Part")
newPart.Color = partColor
newPart.Position = partPosition
newPart.Parent = Workspace
return newPart
end
-- Funktion als Rückruf der Remote-Funktion festlegen
remoteFunction.OnServerInvoke = createPart
Ereignisauslösung - LocalScriptlocal ReplicatedStorage = game:GetService("ReplicatedStorage")-- Holen Sie sich eine Referenz zur Remote-Funktionsinstanzlocal remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")-- Geben Sie eine Farbe und Position an, wenn Sie den Rückruf auslösenlocal newPart = remoteFunction:InvokeServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))-- Geben Sie die zurückgegebene Teilreferenz ausprint("Der Server hat das angeforderte Teil erstellt:", newPart)
Server → Client → Server
Sie können ein Script verwenden, um eine Funktion auf dem Client aufzurufen, indem Sie die Methode InvokeClient() auf einer RemoteFunction aufrufen, jedoch birgt dies ernsthafte Risiken, die wie folgt sind:
- Wenn der Client einen Fehler auslöst, löst auch der Server den Fehler aus.
- Wenn der Client getrennt wird, während er aufgerufen wird, löst InvokeClient() einen Fehler aus.
- Wenn der Client keinen Wert zurückgibt, wartet der Server ewig.
Für Aktionen, die keine bidirektionale Kommunikation erfordern, wie zum Beispiel das Aktualisieren einer GUI, verwenden Sie ein RemoteEvent und kommunizieren Sie vom Server zum Client.
Argumentbeschränkungen
Wenn Sie ein RemoteEvent auslösen oder eine RemoteFunction aufrufen, leitet es alle Argumente weiter, die Sie mit dem Event oder an die Rückruffunktion übergeben. Jeder Typ von Roblox-Objekt, wie ein Enum, Instance oder andere, kann übergeben werden, sowie Luau-Typen wie Zahlen, Strings und Booleans, obwohl Sie sorgfältig die folgenden Einschränkungen untersuchen sollten.
Nicht-String-Indizes
Wenn irgendwelche Indizes einer übergebenen Tabelle von Nicht-String-Typen wie einem Instance, userdata oder Funktion sind, konvertiert Roblox diese Indizes automatisch in Strings.
Ereignisverbindung - LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEventFire(passedTable)
for k, v in passedTable do
print(typeof(k)) --> string
end
end
-- Funktion mit dem Ereignis verbinden
remoteEvent.OnClientEvent:Connect(onEventFire)
Ereignisauslösung - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Auf eingehende Spieler hören und Remote-Event an jeden dispatchen
local function onPlayerAdded(player)
remoteEvent:FireClient(player,
{
[Workspace.Baseplate] = true
}
)
end
Players.PlayerAdded:Connect(onPlayerAdded)
Übergebene Funktionen
Funktionen, die als Argumente für ein RemoteEvent oder RemoteFunction enthalten sind, werden nicht über die Client-Server-Grenze repliziert, wodurch es unmöglich ist, Funktionen remote zu übergeben. Stattdessen ist das resultierende Argument auf der Empfangsseite nil.
Ereignisverbindung - LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onClientEvent(func)
print(func) --> nil
end
remoteEvent.OnClientEvent:Connect(onClientEvent)
Ereignisauslösung - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function testFunction()
print("Hallo Welt!")
end
-- Remote-Event mit Funktion als Argument auslösen
remoteEvent:FireAllClients(testFunction)
Tabellenindizes
Wenn Sie eine Tabelle von Daten übergeben, geben Sie keine gemischte Tabelle mit numerischen und String-Schlüsseln weiter. Geben Sie stattdessen eine Tabelle an, die vollständig aus Schlüssel-Wert-Paaren (Wörterbuch) oder vollständig mit numerischen Indizes besteht.
Ereignisverbindung - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEventFire(player, passedTable)
for k, v in passedTable do
print(k .. " = " .. v)
--> 1 = Schwert
--> 2 = Bogen
--> CharName = Diva Dragonslayer
--> CharClass = Rogue
end
end
-- Funktion mit dem Ereignis verbinden
remoteEvent.OnServerEvent:Connect(onEventFire)
Ereignisauslösung - LocalScriptlocal ReplicatedStorage = game:GetService("ReplicatedStorage")local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")-- Numerisch indizierte Tabellelocal inventoryData = {"Schwert", "Bogen"}-- Wörterbuch-Tabellelocal characterData = {CharName = "Diva Dragonslayer",CharClass = "Rogue"}remoteEvent:FireServer(inventoryData)remoteEvent:FireServer(characterData)
Tabellenidentitäten
Tabellen, die als Argumente an Remote-Events/Rückrufe übergeben werden, werden kopiert, was bedeutet, dass sie nicht genau mit denen übereinstimmen, die beim Auslösen des Events oder beim Aufrufen des Rückrufs bereitgestellt wurden. Ebenso werden Tabellen, die an den Aufrufer zurückgegeben werden, nicht genau mit denen übereinstimmen, die bereitgestellt wurden. Sie können dies demonstrieren, indem Sie das folgende Skript auf einer RemoteFunction ausführen und beobachten, wie sich die Tabellenidentitäten unterscheiden.
Rückrufverbindung - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Rückruffunktion
local function returnTable(player, passedTable)
-- Tabelle identität beim Aufruf ausgeben
print(tostring(passedTable)) --> table: 0x48eb7aead27563d9
return passedTable
end
-- Funktion als Rückruf der Remote-Funktion festlegen
remoteFunction.OnServerInvoke = returnTable
Ereignisauslösung - LocalScriptlocal ReplicatedStorage = game:GetService("ReplicatedStorage")local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")local inventoryData = {"Schwert", "Bogen"}-- Ursprüngliche Tabellenidentität ausgebenprint(tostring(inventoryData)) --> table: 0x059bcdbb2b576549local invokeReturn = remoteFunction:InvokeServer(inventoryData)-- Tabellenidentität bei Rückgabe ausgebenprint(tostring(invokeReturn)) --> table: 0x9fcae7919563a0e9
Metatabellen
Wenn eine Tabelle eine Metatabelle hat, gehen alle Informationen zur Metatabelle bei der Übertragung verloren. In folgendem Codebeispiel ist die Eigenschaft NumWheels Teil der Metatabelle von Car. Wenn der Server die folgende Tabelle empfängt, hat die Tabelle truck die Eigenschaft Name, aber nicht die Eigenschaft NumWheels.
Ereignisverbindung - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEvent(player, param)
print(param) --> {["Name"] = "MeinTruck"}
end
-- Funktion mit dem Ereignis verbinden
remoteEvent.OnServerEvent:Connect(onEvent)
Ereignisauslösung - LocalScriptlocal ReplicatedStorage = game:GetService("ReplicatedStorage")local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")local Car = {}Car.NumWheels = 4Car.__index = Carlocal truck = {}truck.Name = "MeinTruck"setmetatable(truck, Car)-- Ereignis mit einer Tabelle, die eine Metatabelle enthält, auslösenremoteEvent:FireServer(truck)
Nicht replizierte Instanzen
Wenn ein RemoteEvent oder RemoteFunction einen Wert übergibt, der nur für den Sender sichtbar ist, repliziert Roblox ihn nicht über die Client-Server-Grenze hinweg und übergibt nil anstelle des Wertes. Zum Beispiel, wenn ein Script einen Nachkommen von ServerStorage übergibt, erhält der Client, der das Event hört, einen nil-Wert, da dieses Objekt nicht replizierbar ist.
Ereignisauslösung - Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Wird als "nil" empfangen, da der Client nicht auf ServerStorage zugreifen kann
local storedPart = Instance.new("Part")
storedPart.Parent = ServerStorage
local function onPlayerAdded(player)
remoteEvent:FireClient(player, storedPart)
end
Players.PlayerAdded:Connect(onPlayerAdded)
Ähnlich ist es, wenn Sie ein Teil in einem LocalScript erstellen und versuchen, es an ein Script zu übergeben, sieht der Server nil, weil das Teil für den Server nicht replizierbar ist.
Ereignisauslösung - LocalScriptlocal ReplicatedStorage = game:GetService("ReplicatedStorage")local Workspace = game:GetService("Workspace")local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")-- Wird als "nil" empfangen, da der Server nichts von diesem Teil weißlocal clientPart = Instance.new("Part")clientPart.Parent = WorkspaceremoteEvent:FireServer(clientPart)