Fernereignisse und Rückrufe

*Dieser Inhalt wurde mit KI (Beta) übersetzt und kann Fehler enthalten. Um diese Seite auf Englisch zu sehen, klicke hier.

Roblox-Erlebnisse sind standardmäßig Mehrspieler, sodass alle Erlebnisse von Natur aus zwischen dem Server und den verbundenen Clients der Spieler kommunizieren.Im einfachsten Fall werden, wenn Spieler ihre Charaktere bewegen, bestimmte Humanoid Eigenschaften, wie Zustände, an den Server übermittelt, der diese Informationen an andere verbundene Clients weitergibt.

Fernereignisse und Rückrufe ermöglichen es Ihnen, über die Client-Server-Grenze zu kommunizieren:

  • RemoteEvents aktivieren sie eine einseitige kommunikation (senden einer anfrage und nicht für eine antwort aufgeben).
  • UnreliableRemoteEvents aktivieren Sie eine einseitige Kommunikation für Daten, die sich ständig ändern oder nicht kritisch für den Spielzustand sind.Diese Ereignisse tauschen Ordnung und Zuverlässigkeit für verbesserte Erfüllungaus.
  • RemoteFunctions aktivieren sie die zwei-wege-kommunikation (senden einer anfrage undgeben, bis eine antwort vom empfänger erhalten wird).

Im Gegensatz zu bindbaren Ereignissen, die eine begrenztere Funktionalität haben, sind die Anwendungsfälle für entfernte Ereignisse und Funktionen zu zahlreich, um sie aufzulisten:

  • Spielablauf - Grundlegender Gameplay, wie ein Spieler das Ende eines Stufeerreicht, kann ein Remote-Ereignis erfordern.Ein Client-Skript benachrichtigt den Server, und Serverskripte setzen die Position des Spieler:inzurück.
  • Serverüberprüfung - Wenn ein Spieler versucht, einen Trank zu trinken, hat er tatsächlich den Trank? Um Fairness zu gewährleisten, muss der Server die Quelle der Wahrheit für ein Erlebnis sein.Ein Client-Skript kann ein Remote-Ereignis verwenden, um den Server zu benachrichtigen, dass der Spieler einen Trank trinkt, und dann können Server-Skripte entscheiden, ob der Spieler tatsächlich diesen Trank hat und ob er irgendwelche Vorteile verleihen soll.
  • Benutzeroberflächen-Updates - Wenn sich der Spielzustand ändert, können Server-Skripte Remote-Ereignisse verwenden, um Clients über Änderungen an Punkten, Zielen usw. zu informieren
  • Marktplatz-Käufe im Erlebnis - Für eine Beispielimplementierung, die Remote-Funktionen verwendet, siehe Schnelle Abonnementkäufe.

Schnelle Referenz

Die folgenden Tabellen dienen als schnelle Referenz, wie man RemoteEvents und RemoteFunctions verwendet, um zwischen Client und Server zu kommunizieren.

Client → Server >
ClientRemoteEvent:FireServer(args)
ServerRemoteEvent.OnServerEvent:Connect(function(player, args))
Server → Client >
ServerRemoteEvent:FireClient(player, args)
ClientRemoteEvent.OnClientEvent:Connect(function(args))
Server → Alle Clients >
ServerRemoteEvent:FireAllClients(args)
ClientRemoteEvent.OnClientEvent:Connect(function(args))

Fernereignisse

Ein A RemoteEvent Objekt erleichtert asynchrone, einseitige Kommunikation über die Client-Server-Grenze ohne eine Antwort zu geben.

Um eine neue RemoteEvent über das Explorer Fenster in Studio zu erstellen:

  1. Bewegen Sie den Mauszeiger über den Container, in den Sie die RemoteEvent einfügen möchten.Um sowohl den Server- als auch den Client-Zugriff zu gewährleisten, muss es an einem Ort sein, an dem beide Seiten es sehen können, wie z. B. ReplicatedStorage, obwohl es in manchen Fällen angemessen ist, es in Workspace oder innerhalb eines Tool zu speichern.
  2. Klicken Sie auf die Schaltfläche , die rechts vom Namen des Containers erscheint, und fügen Sie eine RemoteEvent Instanz ein.
  3. Benenne die Instanz um, um ihren Zweck zu beschreiben.

Sobald du ein RemoteEvent erstellt hast, kann es die einseitige Kommunikation von Client zu Server , von Server zu Client oder von Server zu allen Clients erleichtern.

Client → Server
>

Server → Client
>

Server → Alle Clients
>

Client -> Server

Du kannst ein LocalScript verwenden, um ein Ereignis auf dem Server auszulösen, indem du die FireServer() auf einem RemoteEvent aufrufst.Wenn du Argumente an FireServer() übermittelst, werden sie an den Event-Handler auf dem Server mit bestimmten Einschränkungen weitergegeben.Beachten Sie, dass der erste Parameter des Event-Handlers auf dem Server immer das Player Objekt des Clients ist, der es aufruft, und zusätzliche Parameter folgen.

ClientRemoteEvent:FireServer(args)
ServerRemoteEvent.OnServerEvent:Connect(function(player, args))

Die folgende Script verbindet einen Event-Handler mit OnServerEvent, der auf dem Server ein neues Part erstellt.Die begleitende ruft dann auf die Instanz mit dem gewünschten und für das Teil auf.

Ereignisverbindung - Skript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- Erhalte einen Verweis auf die Instanz
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onCreatePart(player, partColor, partPosition)
print(player.Name .. " fired the RemoteEvent")
local newPart = Instance.new("Part")
newPart.Color = partColor
newPart.Position = partPosition
newPart.Parent = Workspace
end
-- Funktion zum Verbinden mit Ereignis
remoteEvent.OnServerEvent:Connect(onCreatePart)
Ereignisauslösung - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Erhalte einen Verweis auf die Instanz
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Feuere das Remote-Ereignis ab und übermittle zusätzliche Argumente
remoteEvent:FireServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))

Server → Client

Du kannst ein Script verwenden, um ein Ereignis auf einem Client auszulösen, indem du die FireClient() -Methode auf einem RemoteEvent aufrufst.Das erste Argument für FireClient() ist das Player Objekt des Clients, auf das Sie auf das Ereignis antworten möchten, und zusätzliche Argumente werden an den Client mit bestimmten Einschränkungen weitergegeben.Beachten Sie, dass der Event-Handler das Player Objekt als sein erstes Argument nicht enthalten muss, weil Sie den Spieler auf dem Client mit Players.LocalPlayer bestimmen können.

ServerRemoteEvent:FireClient(player, args)
ClientRemoteEvent.OnClientEvent:Connect(function(args))

Die folgende LocalScript verbindet einen Event-Handler mit dem OnClientEvent Ereignis.Die beigefügte Script hört dann auf eingehende Spieler auf den Server und ruft FireClient() für jeden mit zufälligen Daten auf.

Veranstaltungsverbindung - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Erhalte einen Verweis auf die Instanz
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local player = Players.LocalPlayer
local function onNotifyPlayer(maxPlayers, respawnTime)
print("[Client] Event received by player", player.Name)
print(maxPlayers, respawnTime)
end
-- Funktion zum Verbinden mit Ereignis
remoteEvent.OnClientEvent:Connect(onNotifyPlayer)
Ereignisabschuss - Skript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Erhalte einen Verweis auf die Instanz
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Höre auf eingehende Spieler und sende ein Remote-Ereignis an jeden
local function onPlayerAdded(player)
print("[Server] Firing event to player", player.Name)
remoteEvent:FireClient(player, Players.MaxPlayers, Players.RespawnTime)
end
Players.PlayerAdded:Connect(onPlayerAdded)

Server -> alle Clients

Du kannst ein Script verwenden, um ein Ereignis auf allen Clients auszulösen, indem du die FireAllClients() Methode auf einem RemoteEvent aufrufst.Im Gegensatz zu FireClient() erfordert die Methode FireAllClients() kein Player -Objekt, da sie alle Clients mit RemoteEvent feuert.

ServerRemoteEvent:FireAllClients(args)
ClientRemoteEvent.OnClientEvent:Connect(function(args))

Die folgende LocalScript verbindet einen Event-Handler mit dem OnClientEvent Ereignis, das eine verbleibende Countdown-Zeit ausgibt.Die begleitende Script ruft dann alle Sekunde FireAllClients() in einer Schleife auf, um für alle Clients die RemoteEvent zu feuern.

Veranstaltungsverbindung - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Erhalte einen Verweis auf die Instanz
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onTimerUpdate(seconds)
print(seconds)
end
-- Funktion zum Verbinden mit Ereignis
remoteEvent.OnClientEvent:Connect(onTimerUpdate)
Ereignisabschuss - Skript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Erhalte einen Verweis auf die Instanz
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local countdown = 5
-- Feuere das Remote-Ereignis jede Sekunde ab, bis die Zeit abläuft
for timeRemaining = -1, countdown do
remoteEvent:FireAllClients(countdown - timeRemaining)
task.wait(1)
end

Fernanrufe

Ein A RemoteFunction Objekt erleichtert die synchronische, zweispurige Kommunikation über die Client-Server-Grenze.Der Absender einer Remotefunktion wird ausgeben, bis er eine Antwort vom Empfänger erhält.

Um eine neue RemoteFunction über das Explorer Fenster in Studio zu erstellen:

  1. Bewegen Sie den Mauszeiger über den Container, in den Sie die RemoteFunction einfügen möchten.Um sowohl den Server- als auch den Client-Zugriff zu gewährleisten, muss es an einem Ort sein, an dem beide Seiten es sehen können, wie z. B. ReplicatedStorage, obwohl es in manchen Fällen angemessen ist, es in Workspace oder innerhalb eines Tool zu speichern.
  2. Klicken Sie auf die Schaltfläche , die rechts vom Namen des Containers erscheint, und fügen Sie eine RemoteFunction Instanz ein.
  3. Benenne die Instanz um, um ihren Zweck zu beschreiben.

Sobald du ein RemoteFunction erstellt hast, kann es die Kommunikation zwischen Client und Server oder zwischen Server und Client erleichtern.

Client → Server → Client
>

Server → Client → Server
>

Client -> Server -> Client

Du kannst ein LocalScript verwenden, um eine Funktion auf dem Server aufzurufen, indem du die InvokeServer() auf einem RemoteFunction aufrufst.Im Gegensatz zu einem Remote-Ereignis lässt das LocalScript, das die RemoteFunction aufruft, bis der Rückruf zurückkehrt.Argumente, die du an InvokeServer() übermittelst, werden an den OnServerInvoke Rückruf des RemoteFunction mit bestimmten Einschränkungen weitergegeben.Beachten Sie, dass, wenn Sie mehrere Rückrufe auf die gleiche RemoteFunction definieren, nur die letzte Definition ausgeführt wird.

ClientRemoteFunction:InvokeServer(args)
ServerRemoteFunction.OnServerInvoke = function(player, args)

Die folgende Script definiert die Rückruffunktion über OnServerInvoke und gibt die angeforderte Part durch ihren return Wert zurück.Die begleitende LocalScript ruft dann InvokeServer() mit zusätzlichen Argumenten auf, die die angeforderte Teilfarbe und -position definieren.

Rückrufverbindung - Skript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- Erhalte einen Verweis auf die Instanz
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Rückruffunktion
local function createPart(player, partColor, partPosition)
print(player.Name .. " requested a new part")
local newPart = Instance.new("Part")
newPart.Color = partColor
newPart.Position = partPosition
newPart.Parent = Workspace
return newPart
end
-- Funktion als Callbackder Fernfunktion festlegen
remoteFunction.OnServerInvoke = createPart
Ereignisaufruf - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Erhalte einen Verweis auf die Instanz
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Geben Sie eine Farbe und eine Position bei der Auslösung des Callbackan
local newPart = remoteFunction:InvokeServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))
-- Geben Sie die zurückgegebene Teilreferenz aus
print("The server created the requested part:", newPart)

Server → Kunde → Server

Du kannst eine Script verwenden, um eine Funktion auf dem Client aufzurufen, indem du die InvokeClient() -Methode auf einem RemoteFunction aufrufst, aber es hat ernste Risiken wie folgt:

  • Wenn der Client einen Fehler wirft, wirft der Server den Fehler ebenfalls.
  • Wenn der Client während der Ausführung abbricht, InvokeClient() wirft er einen Fehler.
  • Wenn der Client keinen Wert zurückgibt, gibt der Server für immer auf.

Für Aktionen, die keine zweckmäßige Kommunikation erfordern, wie das Aktualisieren einer grafische Benutzeroberfläche, verwende ein RemoteEvent und kommuniziere vom Server zum Client.

Argumentbeschränkungen

Wenn du ein RemoteEvent abfeuerst oder eine RemoteFunction aufrufst, leitet es alle Argumente weiter, die du mit dem Ereignis oder der Rückruffunktion übermittelst.Jede Art von Roblox-Objekt wie ein Enum , Instance oder andere kann übergeben werden, sowie Luau-Typen wie Zahlen, Zeichen und Booleen, obwohl Sie die folgenden Einschränkungen sorgfältig erforschen sollten.

Nicht-Zeichen-Indizes

Wenn irgendeine Indizes eines durchgegebenen Tabells nicht-string-Typen wie ein Instance , Benutzerdaten oder Funktion sind, konvertiert Roblox diese Indizes automatisch in Zeichenketten.

Veranstaltungsverbindung - 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 zum Verbinden mit Ereignis
remoteEvent.OnClientEvent:Connect(onEventFire)
Ereignisabschuss - Skript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Höre auf eingehende Spieler und sende ein Remote-Ereignis an jeden
local function onPlayerAdded(player)
remoteEvent:FireClient(player,
{
[Workspace.Baseplate] = true
}
)
end
Players.PlayerAdded:Connect(onPlayerAdded)

Abgegebene Funktionen

Funktionen, die als Argumente für ein oder enthalten sind, werden nicht auf der Client-Server-Grenze repliziert, wodurch es unmöglich wird, Funktionen remote zu übergeben.Stattdessen wird das daraus resultierende Argument auf der Empfängerseite nil sein.

Veranstaltungsverbindung - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onClientEvent(func)
print(func) --> null
end
remoteEvent.OnClientEvent:Connect(onClientEvent)
Ereignisabschuss - Skript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function testFunction()
print("Hello world!")
end
-- Feuere ein Remote-Ereignis mit Funktion als Argument ab
remoteEvent:FireAllClients(testFunction)

Tabelleindeksierung

Wenn du eine Tabelle mit Daten durchläufst, sende keine gemischte Tabelle mit numerischen und Zeichenketten-Schlüsseln.Stattdessen geben Sie eine Tabelle ein, die ausschließlich aus Schlüssel-Wert-Paaren (Wörterbuch) oder ganz numerischen Indizes besteht.

Ereignisverbindung - Skript

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-Drachenschlächter
--> CharClass = Übeltäter
end
end
-- Funktion zum Verbinden mit Ereignis
remoteEvent.OnServerEvent:Connect(onEventFire)
Ereignisauslösung - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Zahlweise indexierte Tabelle
local inventoryData = {
"Sword", "Bow"
}
-- Wörterbuch-Tabelle
local characterData = {
CharName = "Diva Dragonslayer",
CharClass = "Rogue"
}
remoteEvent:FireServer(inventoryData)
remoteEvent:FireServer(characterData)

Tisch-Identitäten

Tabellen, die als Argumente an ferne Ereignisse/Callbacks übergeben werden, werden kopiert, was bedeutet, dass sie nicht exakt gleich sind, wie die bereitgestellten, wenn Sie das Ereignis abfeuern oder den Rückruf auslösen.Tabellen, die an den Invoker zurückgegeben werden, entsprechen auch nicht genau denen, die bereitgestellt wurden.Du kannst dies durch Ausführen des folgenden Skripts auf einem RemoteFunction und Beobachten, wie sich die Tabellenidentitäten unterscheiden, demonstrieren.

Rückrufverbindung - Skript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Rückruffunktion
local function returnTable(player, passedTable)
-- Ausgabetabellen-Identität bei Aufruf
print(tostring(passedTable)) --> tabelle: 0x48eb7aead27563d9
return passedTable
end
-- Funktion als Callbackder Fernfunktion festlegen
remoteFunction.OnServerInvoke = returnTable
Ereignisaufruf - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
local inventoryData = {
"Sword", "Bow"
}
-- Ausgabe der ursprünglichen Tabellen-ID
print(tostring(inventoryData)) --> tabelle: 0x059bcdbb2b576549
local invokeReturn = remoteFunction:InvokeServer(inventoryData)
-- Ausgabetabellen-Identität bei zurückgeben
print(tostring(invokeReturn)) --> table: 0x9fcae7919563a0e9

Metatabellen

Wenn ein Tisch ein Metatable hat, geht bei der Übertragung alle Metatable-Informationen verloren.Im folgenden Codebeispiel ist das Eigenschaft NumWheels Teil des Car messbaren.Wenn der Server die folgende Tabelle erhält, hat die Tabelle die Eigenschaft aber nicht die Eigenschaften.

Ereignisverbindung - Skript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEvent(player, param)
print(param) --> { ["Name"] = "MyTruck"]}
end
-- Funktion zum Verbinden mit Ereignis
remoteEvent.OnServerEvent:Connect(onEvent)
Ereignisauslösung - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local Car = {}
Car.NumWheels = 4
Car.__index = Car
local truck = {}
truck.Name = "MyTruck"
setmetatable(truck, Car)
-- Feuerevent mit Tabelle einschließlich eines Metatables
remoteEvent:FireServer(truck)

Nicht replizierte Instanzen

Wenn ein RemoteEvent oder RemoteFunction einen Wert überträgt, der nur für den Absender sichtbar ist, repliziert Roblox ihn nicht über die Client-Server-Grenze und gibt stattdessen den Wert nil anstelle des Werts an.Wenn zum Beispiel ein Script einen Nachkommen von ServerStorage passt, erhält der Client, der auf das Ereignis hört, einen nil Wert, weil dieses Objekt für den Client nicht replizierbar ist.

Ereignisabschuss - Skript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Wird als "null" 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)

Ebenso, wenn du ein Teil in einem LocalScript erstellst und versuchst, es an einen Script zu übergeben, sieht der Server nil an, weil das Teil für den Server nicht replizierbar ist.

Ereignisauslösung - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Wird als "null" empfangen, weil der Server nichts von diesem Teil weiß
local clientPart = Instance.new("Part")
clientPart.Parent = Workspace
remoteEvent:FireServer(clientPart)