Doświadczenia Roblox są domyślnie wieloosobowe, więc wszystkie doświadczenia są z natury komunikowane między serwerem a połączonymi klientami graczy.W najprostszej sytuacji, gdy gracze przesuwają swoje postacie, pewne właściwości Humanoid stanów są przekazywane na serwer, który przekazuje tę informację innym połączonym klientom.
Wydarzenia zdalne i wezwania pozwalają na komunikację przez granicę klienta-serwera:
- RemoteEvents włącz jednostronną komunikację (wysyłanie żądania i nie poddawanie się w odpowiedzi).
- UnreliableRemoteEvents włącz jednostronną komunikację dla danych, które zmieniają się ciągle lub nie są krytyczne dla stanu gryTe wydarzenia handlują zamawianiem i niezawodnością w celu poprawy wykonywaniesieci.
- RemoteFunctions włącz komunikację dwukierunkową (wysyłanie żądania i poddawanie, aż otrzymane zostanie odpowiedź od odbiorca).
W przeciwieństwie do wiązanych wydarzeń, które mają mniejszą użyteczność, przypadki użycia zdalnych wydarzeń i funkcji są zbyt liczne, aby je wymienić:
- Grywalność - Podstawowa rozgrywka, tak jak gracz osiągający koniec poziomu, może wymagać zdarzenia zdalnego.Skrypt klienta powiadamia serwer, a skrypty serwera resetują pozycję gracza.
- Weryfikacja serwera - Jeśli gracz próbuje wypić miksturę, czy rzeczywiście ma tę miksturę? Aby zapewnić uczciwość, serwer musi być źródłem prawdy dla doświadczenia.Skrypt klienta może używać zdarzenia zdalnego, aby powiadomić serwer, że gracz pije miksturę, a następnie skrypty serwera mogą decydować, czy gracz rzeczywiście ma tę miksturę i czy może przyznawać jakiekolwiek korzyści.
- Aktualizacje interfejsu użytkownika - Wraz ze zmianą stanu gry skrypty serwera mogą używać zdarzeń zdalnych, aby powiadomić klientów o zmianach wyników, celów itp.
- Zakupy na rynku doświadczeń - Dla przykładowej implementacji, która wykorzystuje zdalne funkcje, zobacz Prompt zakup subskrypcji.
Szybki odniesienie
Poniższe tabele służą jako szybkie odniesienie do tego, jak używać RemoteEvents i RemoteFunctions do komunikacji między klientem a serwerem.
Klient → Serwer | |
---|---|
Klienci | RemoteEvent:FireServer(args) |
Serwer | RemoteEvent.OnServerEvent:Connect(function(player, args)) |
Serwer → Klient | |
Serwer | RemoteEvent:FireClient(player, args) |
Klienci | RemoteEvent.OnClientEvent:Connect(function(args)) |
Serwer → Wszyscy klienci > | |
Serwer | RemoteEvent:FireAllClients(args) |
Klienci | RemoteEvent.OnClientEvent:Connect(function(args)) |
Wydarzenia zdalne
Przedmiot RemoteEvent ułatwia asynchroniczną, jednostronną komunikację na granicy klient-serwer bez oddawania odpowiedzi.
Aby utworzyć nowy RemoteEvent za pomocą okna Explorer w Studio:
- Najedź na pojemnik, do którego chcesz wstawić RemoteEvent.Aby zapewnić dostęp zarówno serwera, jak i klienta, musi znajdować się w miejscu, w którym obie strony mogą go zobaczyć, takim jak ReplicatedStorage, choć w niektórych przypadkach właściwe jest przechowywanie go w Workspace lub wewnątrz Tool.
- Kliknij przycisk ⊕ , który pojawia się po prawej stronie nazwy kontenera i wstaw instancję RemoteEvent .
- Zmień nazwę instancji, aby opisać jej cel.
Po utworzeniu RemoteEvent może ułatwić jednostronną komunikację z klienta na serwerze , z serwera do klienta lub z serwera do wszystkich klientów.



Klient → serwer
Możesz użyć , aby uruchomić wydarzenie na serwerze poprzez wezwanie metody na .Jeśli przekażesz argumenty do FireServer(), przekażą się do menedżera zdarzeń na serwerze z pewnymi ograniczeniami .Zauważ, że pierwszy parametr obsługi zdarzenia na serwerze zawsze jest obiektem Player klienta, który go wzywa, a następnie dodatkowe parametry obserwować.
Klienci | RemoteEvent:FireServer(args) |
Serwer | RemoteEvent.OnServerEvent:Connect(function(player, args)) |
Następujący Script łączy menedżera zdarzeń z OnServerEvent który tworzy nowe Part na serwerze.Następnie towarzyszący LocalScript wezwuje FireServer() na instancji RemoteEvent z pożądanym Color i Position dla części.
Połączenie zdarzenia - Skrypt
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- Zdobądź odniesienie do zdalnej instancji instancja
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
-- Połącz funkcję z wydarzeniem
remoteEvent.OnServerEvent:Connect(onCreatePart)
Strzelanie zdarzeń - Lokalny skrypt
local ReplicatedStorage = game:GetService("ReplicatedStorage")-- Zdobądź odniesienie do zdalnej instancji instancjalocal remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")-- Wystrzel zdarzenie zdalne i przekaż dodatkowe argumentyremoteEvent:FireServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))
Serwer → klient
Możesz użyć , aby uruchomić wydarzenie na klientzie poprzez wezwanie metody na .Pierwszy argument dla jest obiektem klienta, na który chcesz odpowiedzieć na wydarzenie, a dodatkowe argumenty przekazane są do klienta z pewnymi ograniczeniami .Zauważ, że menadżer zdarzeń nie musi zawierać obiektu Player jako pierwszego argumentu, ponieważ możesz określić gracza na klientzie za pomocą Players.LocalPlayer .
Serwer | RemoteEvent:FireClient(player, args) |
Klienci | RemoteEvent.OnClientEvent:Connect(function(args)) |
Następujący LocalScript łączy menadżera zdarzeń z wydarzeniem OnClientEvent .Towarzyszący Script wysłuchuje wtedy nadchodzących graczy na serwer i dzwoni FireClient() dla każdego z dowolnymi danymi.
Połączenie z wydarzeniem - LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Zdobądź odniesienie do zdalnej instancji instancja
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
-- Połącz funkcję z wydarzeniem
remoteEvent.OnClientEvent:Connect(onNotifyPlayer)
Strzelanie zdarzeń - Skrypt
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Zdobądź odniesienie do zdalnej instancji instancja
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Słuchaj nadchodzących graczy i wysyłaj zdalne wydarzenie do każdego
local function onPlayerAdded(player)
print("[Server] Firing event to player", player.Name)
remoteEvent:FireClient(player, Players.MaxPlayers, Players.RespawnTime)
end
Players.PlayerAdded:Connect(onPlayerAdded)
Serwer → wszystkie klienty
Możesz użyć Script, aby uruchomić wydarzenie na wszystkich klientach, wywołując metodę FireAllClients() na RemoteEvent.W przeciwieństwie do FireClient() , metoda FireAllClients() nie wymaga obiektu Player, ponieważ wysyła RemoteEvent do wszystkich klientów.
Serwer | RemoteEvent:FireAllClients(args) |
Klienci | RemoteEvent.OnClientEvent:Connect(function(args)) |
Następujący LocalScript łączy menedżera zdarzeń z wydarzeniem OnClientEvent, które wyświetla czas odliczania pozostały.Następnie towarzyszący Script wzywa FireAllClients() w pętli co sekundę, aby uruchomić RemoteEvent dla wszystkich klientów.
Połączenie z wydarzeniem - LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Zdobądź odniesienie do zdalnej instancji instancja
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onTimerUpdate(seconds)
print(seconds)
end
-- Połącz funkcję z wydarzeniem
remoteEvent.OnClientEvent:Connect(onTimerUpdate)
Strzelanie zdarzeń - Skrypt
local ReplicatedStorage = game:GetService("ReplicatedStorage")-- Zdobądź odniesienie do zdalnej instancji instancjalocal remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")local countdown = 5-- Strzelaj zdarzenie zdalne co sekundę, aż czas wygaśniefor timeRemaining = -1, countdown doremoteEvent:FireAllClients(countdown - timeRemaining)task.wait(1)end
Zdalne wezwania powrotne
Przedmiot RemoteFunction ułatwia synchroniczną, dwukierunkową komunikację na granicy klient-serwer.Wysyłający funkcji zdalnej będzie czekać, dopóki nie otrzyma odpowiedzi od odbiorca.
Aby utworzyć nowy RemoteFunction za pomocą okna Explorer w Studio:
- Najedź na pojemnik, do którego chcesz wstawić RemoteFunction.Aby zapewnić dostęp zarówno serwera, jak i klienta, musi znajdować się w miejscu, w którym obie strony mogą go zobaczyć, takim jak ReplicatedStorage, choć w niektórych przypadkach właściwe jest przechowywanie go w Workspace lub wewnątrz Tool.
- Kliknij przycisk ⊕ , który pojawia się po prawej stronie nazwy kontenera i wstaw instancję RemoteFunction .
- Zmień nazwę instancji, aby opisać jej cel.
Po utworzeniu RemoteFunction może ułatwić dwukierunkową komunikację między klientem a serwerem lub między serwerem a klientem.


Klient → serwer → klient
Możesz użyć , aby wezwać funkcję na serwerze poprzez wezwanie metody na .W przeciwieństwie do zdarzenia zdalnego remote, które wywołuje LocalScript, które wzywa RemoteFunction aż do powrotu wezwania.Argumenty, które przekazujesz do InvokeServer() przekazują się do powrotu OnServerInvoke z pewnymi ograniczeniami RemoteFunction z .Zauważ, że jeśli zdefiniujesz wiele powrotów do tego samego RemoteFunction, tylko ostatnia definicja zostanie wykonana.
Klienci | RemoteFunction:InvokeServer(args) |
Serwer | RemoteFunction.OnServerInvoke = function(player, args) |
Następująca Script określa funkcję powrotną za pomocą OnServerInvoke i zwraca żądaną Part poprzez jej wartość return.Następnie towarzyszący LocalScript wzywa InvokeServer() z dodatkowymi argumentami określającymi pożądaną część koloru i pozycję.
Połączenie powrotne - Skrypt
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- Zdobądź odniesienie do instancji zdalnej funkcji
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Funkcja powrotu
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
-- Ustaw funkcję jako powrót funkcji zdalnej
remoteFunction.OnServerInvoke = createPart
Wezwanie wydarzenia - LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")-- Zdobądź odniesienie do instancji zdalnej funkcjilocal remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")-- Przekaż kolor i pozycję podczas wzywania powrotulocal newPart = remoteFunction:InvokeServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))-- Wyświetl odwołanie do zwróconej częściprint("The server created the requested part:", newPart)
Serwer → klient → serwer
Możesz użyć Script , aby wezwać funkcję na klientzie, wywołując metodę InvokeClient() na RemoteFunction, ale ma poważne ryzyko, jak następuje:
- Jeśli klient rzuca błąd, serwer również rzuca błąd.
- Jeśli klient odłączy się, gdy jest wzywany, InvokeClient() wyśle błąd.
- Jeśli klient nie zwraca wartości, serwer zachowuje się na zawsze.
Dla działań, które nie wymagają dwukierunkowej komunikacji, takich jak aktualizacja interfejsu GUI, użyj RemoteEvent i komunikuj się z serwera na klienta.
Ograniczenia argumentów
Kiedy wystrzelasz RemoteEvent lub wzywasz RemoteFunction, przekazujesz wszystkie argumenty, które przekazujesz z wydarzeniem lub do funkcji powrotu.Wszelki rodzaj obiektu Roblox, takiego jak Enum , Instance lub inne, może zostać przekazany, a także typy Luau, takie jak liczby, ciągi i booliany, choć powinieneś uważnie przeanalizować następujące ograniczenia.
Nie stringowe indeksy
Jeśli którekolwiek indeksy z przekazanego stołu są typami nietekstowymi, takimi jak Instance , dane użytkownika lub funkcja, Roblox automatycznie konwertuje te indeksy na struny.
Połączenie z wydarzeniem - LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEventFire(passedTable)
for k, v in passedTable do
print(typeof(k)) --> ciąg
end
end
-- Połącz funkcję z wydarzeniem
remoteEvent.OnClientEvent:Connect(onEventFire)
Strzelanie zdarzeń - Skrypt
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Słuchaj nadchodzących graczy i wysyłaj zdalne wydarzenie do każdego
local function onPlayerAdded(player)
remoteEvent:FireClient(player,
{
[Workspace.Baseplate] = true
}
)
end
Players.PlayerAdded:Connect(onPlayerAdded)
Przekazane funkcje
Funkcje włączone jako argumenty dla RemoteEvent lub RemoteFunction zostaną nie skopiowane na granicy klient-serwer, co uniemożliwia przekazywanie funkcji zdalnie.Zamiast tego wynikowy argument po stronie odbiorczej będzie nil .
Połączenie z wydarzeniem - LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onClientEvent(func)
print(func) --> nil
end
remoteEvent.OnClientEvent:Connect(onClientEvent)
Strzelanie zdarzeń - Skrypt
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function testFunction()
print("Hello world!")
end
-- Wyzwól zdarzenie zdalne z funkcją jako argumentem
remoteEvent:FireAllClients(testFunction)
Indeksowanie tabel
Jeśli przekazujesz tabelę danych, nie przekazuj mieszanej tabeli liczbowych i kluczy tekstowych.Zamiast tego przekaż tabelę, która składa się w całości z par klucz-wartość (słownik) lub w całości z indeksów liczbowych.
Połączenie zdarzenia - Skrypt
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 = Miecz
--> 2 = Łuk
--> Nazwa postaci = Diva Dragonslayer
--> CharClass = Szkodnik
end
end
-- Połącz funkcję z wydarzeniem
remoteEvent.OnServerEvent:Connect(onEventFire)
Strzelanie zdarzeń - Lokalny skrypt
local ReplicatedStorage = game:GetService("ReplicatedStorage")local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")-- Tablica numerowo indeksowanalocal inventoryData = {"Sword", "Bow"}-- Tabela słownikalocal characterData = {CharName = "Diva Dragonslayer",CharClass = "Rogue"}remoteEvent:FireServer(inventoryData)remoteEvent:FireServer(characterData)
Tożsamości tabel
Tabele przekazywane jako argumenty do zdalnych wydarzeń/ callbacków są kopiowane, co oznacza, że nie będą dokładnie równoważne tym dostarczonym podczas uruchamiania wydarzenia lub wzywania powrotu.Nie będą również tabele zwracane do invokera dokładnie odpowiadały tym dostarczonym.Możesz to pokazać, uruchamiając następujący skrypt na RemoteFunction i obserwując, jak różnią się identyfikatory tabeli.
Połączenie powrotne - Skrypt
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Funkcja powrotu
local function returnTable(player, passedTable)
-- Wyświetlanie tożsamości tablicy wyników przy wezwaniu
print(tostring(passedTable)) --> stół: 0x48eb7aead27563d9
return passedTable
end
-- Ustaw funkcję jako powrót funkcji zdalnej
remoteFunction.OnServerInvoke = returnTable
Wezwanie wydarzenia - LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")local inventoryData = {"Sword", "Bow"}-- Wyświetl oryginalną tożsamość tablicyprint(tostring(inventoryData)) --> stół: 0x059bcdbb2b576549local invokeReturn = remoteFunction:InvokeServer(inventoryData)-- Wyświetlanie tożsamości tabeli po powrocieprint(tostring(invokeReturn)) --> table: 0x9fcae7919563a0e9
Metatabelki
Jeśli stół ma metatable, wszystkie informacje metatable są utracone w transferze.W następnym przykładzie kodu właściwość NumWheels jest częścią Car metatable.Kiedy serwer otrzymuje poniższą tabelę, tabela ma właściwość , ale nie ma właściwości .
Połączenie zdarzenia - Skrypt
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEvent(player, param)
print(param) --> { ["Nazwa"] = "MyTruck"}
end
-- Połącz funkcję z wydarzeniem
remoteEvent.OnServerEvent:Connect(onEvent)
Strzelanie zdarzeń - Lokalny skrypt
local ReplicatedStorage = game:GetService("ReplicatedStorage")local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")local Car = {}Car.NumWheels = 4Car.__index = Carlocal truck = {}truck.Name = "MyTruck"setmetatable(truck, Car)-- Wydarzenie ognia z tabelą, w której znajduje się metatableremoteEvent:FireServer(truck)
Instancje niezareplikowane
Jeśli RemoteEvent lub RemoteFunction przekazuje wartość widoczną tylko dla nadawcy, Roblox nie replikuje jej poza granicą klienta-serwera i przekazuje nil zamiast wartości.Na przykład, jeśli Script przechodzi potomek ServerStorage , klient słuchający wydarzenia otrzyma wartość nil ponieważ ten obiekt nie jest replikowany dla klienta.
Strzelanie zdarzeń - Skrypt
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Zostanie otrzymany jako "null", ponieważ klient nie może uzyskać dostępu do ServerStorage
local storedPart = Instance.new("Part")
storedPart.Parent = ServerStorage
local function onPlayerAdded(player)
remoteEvent:FireClient(player, storedPart)
end
Players.PlayerAdded:Connect(onPlayerAdded)
Podobnie, jeśli utworzysz część w LocalScript i spróbujesz przekazać ją do Script, serwer zobaczy nil ponieważ część nie jest replikowalna dla serwera.
Strzelanie zdarzeń - Lokalny skrypt
local ReplicatedStorage = game:GetService("ReplicatedStorage")local Workspace = game:GetService("Workspace")local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")-- Zostanie otrzymany jako "null", ponieważ serwer nie wie o tej częścilocal clientPart = Instance.new("Part")clientPart.Parent = WorkspaceremoteEvent:FireServer(clientPart)