Zdarzenia i wezwania zdalne

*Ta zawartość została przetłumaczona przy użyciu narzędzi AI (w wersji beta) i może zawierać błędy. Aby wyświetlić tę stronę w języku angielskim, kliknij tutaj.

Doświadczenia Roblox są wieloosobowe domyślnie, więc wszystkie doświadczenia zasadniczo komunikują się między serwerem a połączonymi klientami graczy. W najprostszym przypadku, gdy gracze przesuwają swoje postacie, niektóre Humanoid właściwości, takie jak stan, są komunikowane z serwerem, który przekazuje tę informację do innych połączonych klientów.

Zdalne wydarzenia i wezwania pozwalają na komunikację pomiędzy granicą klienta-serwera:

  • RemoteEvents włącz jednokierunkową komunikację (wysyłanie prośby i nie dostarczanie dla odpowiedzi).
  • UnreliableRemoteEvents włącz jednokierunkową komunikację dla danych, które się szybko zmieniają lub nie są krytyczne dla stanu gry. Te wydarzenia wymieniają i zapewniają wiarygodność dla poprawy wykonywaniesieci.
  • RemoteFunctions włącz dwukolorową komunikację (wysyłanie prośby i oczekiwanie na otrzymanie odpowiedzi od odbiorca).

W przeciwieństwie do powiązanych wydarzeń, które mają ograniczoną funkcjonalność, przypadki użycia dla zdalnych wydarzeń i funkcji są zbyt liczne, aby je wymienić:

  • GAMEPLAY - Podstawowe rozgrywka, takie jak osiągnięcie gracza końca poziomu, może wymagać zdalnego zdarzenia. Skrypt klienta informuje serwer i serwerowe skrypty zresetują pozycję gracza.
  • Zweryfikacja serwera - Jeśli gracz próbuje wypić eliksir, czy on naprawdę ma ten eliksir? Aby zagwarantować uczciwość, serwer musi być źródłem prawdy dla doświadczenia. Skrypt klienta może użyć zdalnego wydarzenia, aby powiadomić serwer, że gracz wypija eliksir, a następnie serwer może zdecydować,
  • Aktualizacje interfejsu użytkownika - gdy stan gry się zmienia, serwerowe skrypty mogą używać zdarzeń zdalnych, aby poinformować klientów o zmianach wyników, celów itp.
  • Wнутri-ezperyjne zakupy rynkowe - Dla przykładowej implementacji używającej zasadniczo funkcji zdalnych, zobacz Wymagające zakupy subskrypcji .

Szybki przewodnik

Poniższe tabelary służą jako szybki przewodnik dla tego, jak używać RemoteEvents i RemoteFunctions, aby komunikować się między klientem a serwerem.

> >
Klient → Serwer
KlientRemoteEvent:FireServer(args)
SerwerRemoteEvent.OnServerEvent:Connect(function(player, args))
Serwer → Klient
SerwerRemoteEvent:FireClient(player, args)
KlientRemoteEvent.OnClientEvent:Connect(function(args))
Serwer → Wszystkie Klienty
SerwerRemoteEvent:FireAllClients(args)
KlientRemoteEvent.OnClientEvent:Connect(function(args))

Wydarzenia zdalne

Obiekt RemoteEvent ułatwia bezasynchroniczną komunikację jednokierunkową między klientem a serwerem bez konieczności dostarczania odpowiedzi.

Aby utworzyć nowy RemoteEvent poprzez okno Explorer w Studio:

  1. Przytrzymajте myszkę na kontenerze, do którego chcesz wstawić RemoteEvent. Aby zagwarantować dostęp zarówno dla serwera, jak i klienta, musi on znajdować się w miejscu, w którym obie strony mogą go zobaczyć, takim jak ReplicatedStorage , choć w niektórych przypadk
  2. Kliknij przycisk , który pojawia się po prawej stronie imienia kontenera i wpisz instancję RemoteEvent .
  3. Zmień nazwę instancji, aby opisać jej cel.

Kiedy stworzysz RemoteEvent, możesz ułatwić jednokierunkową komunikację od klienta do serwera, z serwera do klienta lub z 2>serwera do wszystkich klientów2>.

Klient → Serwer
Serwer → Klient
Serwer → Wszystkie Klienty

Klient → Serwer

Możesz użyć LocalScript , aby wywołać wydarzenie na serwerze poprzez wezwanie metody Class.RemoteEvent:FireServer()|FireServer() na <

KlientRemoteEvent:FireServer(args)
SerwerRemoteEvent.OnServerEvent:Connect(function(player, args))

Poniższy Script połącza węzłowy handlerewentów z OnServerEvent, który tworzy nowy

Połączenie wątku - Skrypt

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Zdobądź odniesienie do instancji zdarzenia 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)
Wydarzenie - Lokalny Skrypt

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Zdobądź odniesienie do instancji zdarzenia instancja
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Wykonaj zdalne wydarzenie i przekaż dodatkowe argumenty
remoteEvent:FireServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))

Serwer → Klient

Możesz użyć Script , aby

SerwerRemoteEvent:FireClient(player, args)
KlientRemoteEvent.OnClientEvent:Connect(function(args))

Następny LocalScript połączy wrażliwy na wydarzenia OnClientEvent z wydarzeniem Script. Załączający 2>Class.Script2> słucha wtedy przychodzących graczy na serwer i wzywa 5>Class.RemoteEvent:FireClient()|FireClient()5> dla każdej z dowolnych dany

Połączenie wątku - Lokalny Skrypt

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Zdobądź odniesienie do instancji zdarzenia 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)
Wydarzenie - Skrypt

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Zdobądź odniesienie do instancji zdarzenia instancja
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Słuchaj zarządzaj zdalnymi wydarzeniami do każdego przychodzącego gracza
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 zainicjować wydarzenie na wszystkich klientach, wzywając metodę Class.RemoteEvent:FireAllClients()|FireAllClients()</

SerwerRemoteEvent:FireAllClients(args)
KlientRemoteEvent.OnClientEvent:Connect(function(args))

Poniższy LocalScript połączyć z wydarzeniem OnClientEvent, które wyświetla pozostały czas odliczania. Z kolei Script wzywa co sekundę 2>Class.RemoteEvent:FireAllClients()|FireAllClients()2> w pęt

Połączenie wątku - Lokalny Skrypt

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Zdobądź odniesienie do instancji zdarzenia instancja
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onTimerUpdate(seconds)
print(seconds)
end
-- Połącz funkcję z wydarzeniem
remoteEvent.OnClientEvent:Connect(onTimerUpdate)
Wydarzenie - Skrypt

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Zdobądź odniesienie do instancji zdarzenia instancja
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local countdown = 5
-- Wykonuj zdalne wydarzenie co druga sekunda, aż czas wygasa
for timeRemaining = -1, countdown do
remoteEvent:FireAllClients(countdown - timeRemaining)
task.wait(1)
end

Zwolnij

Obiekt RemoteFunction ułatwia komunikację synchronizowaną dwukolorową między granicą klienta-serwera. Wysyłacz funkcji zdalnej będzie wygrywać do czasu otrzymania odpowiedzi od odbiorca.

Aby utworzyć nowy RemoteFunction poprzez okno Explorer w Studio:

  1. Przytrzymajте myszkę na kontenerze, do którego chcesz wstawić RemoteFunction. Aby zagwarantować dostęp zarówno dla serwera, jak i klienta, musi on znajdować się w miejscu, w którym obie strony mogą go zobaczyć, takim jak ReplicatedStorage , choć w niektórych przypadk
  2. Kliknij przycisk , który pojawia się po prawej stronie imienia kontenera i wpisz instancję RemoteFunction .
  3. Zmień nazwę instancji, aby opisać jej cel.

Gdy stworzysz RemoteFunction, może ułatwić komunikację dwukolorową między klientem a serwerem lub między serwerem a klientem.

Klient → Serwer → Klient
Serwer → Klient → Serwer

Klient → Serwer → Klient

Możesz użyć LocalScript , aby wejść w posiadanie funkcji na serwer poprzez wezwanie metody Class.RemoteFunction:Execute

KlientRemoteFunction:InvokeServer(args)
SerwerRemoteFunction.OnServerInvoke = function(player, args)

Poniższy Script definuje funkcję zwrotu poprzez OnServerInvoke i zwraca żądany Part poprzez jego wartość 2>return2>. Następny 5>Class.LocalScript5> wzywa 8>

Callback połączenie - Skrypt

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Zdobądź odniesienie do instancji funkcji zdalnej
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Funkcja zwrotu
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 wzwanie funkcji zdalnej
remoteFunction.OnServerInvoke = createPart
Wyzwanie wydarzenia - Lokalny Skrypt

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Zdobądź odniesienie do instancji funkcji zdalnej
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Przekaż kolor i pozycję podczas wzywania funkcji
local newPart = remoteFunction:InvokeServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))
-- Wyświetl odnośnik części zwróconej
print("The server created the requested part:", newPart)

Serwer → Klient → Serwer

Możesz użyć Script , aby wejść na funkcję na klientze, poprzez wezwanie metody Class.RemoteFunction:ExecuteClient()|ExecuteClient() na Class.RemoteFunction, ale ma poważne ryzyko, jak następuje:

  • Jeśli klient rzuca błędem, serwer rzuca błędem również.
  • Jeśli klient się odłącza podczas uruchamiania, InvokeClient() wyrzuca błąd.
  • Jeśli klient nie zwraca wartości, serwer zachowuje na zawsze.

Dla akcji, które nie wymagają dwukolorowych komunikacji, takich jak aktualizacja interfejsu użytkownika, użyj RemoteEvent i komunikuj się z serwera do klienta.

Ograniczenia argumentów

Gdy wyrzucasz RemoteEvent lub wzywasz RemoteFunction, przekazuje wszystkie argumenty, które przekazujesz z wydarzenia lub funkcji zwrotnej. Każdy rodzaj obiektu Roblox, takiego jak Enum , 2>Class.Instance2> lub inne, może być prz

Niezależne wskaźniki

Jeśli którekolwiek indeksy tabeli przepustej są niestrukturalnymi typami, takimi jak Instance , userdata lub 1>funkcja1>, Roblox automatycznie konwertuje te indeksy w strójce.

Połączenie wątku - Lokalny Skrypt

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)
Wydarzenie - Skrypt

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Słuchaj zarządzaj zdalnymi wydarzeniami do każdego przychodzącego gracza
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, nie będą kopiowane poprzez granicę klient-serwer, uniemożliwiając w ten sposób przesyłanie funkcji zdalnie. Zamiast tego wynik argumentu na stronie odbiorczej będzie 2>nil2>.

Połączenie wątku - Lokalny Skrypt

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onClientEvent(func)
print(func) --> zero
end
remoteEvent.OnClientEvent:Connect(onClientEvent)
Wydarzenie - Skrypt

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function testFunction()
print("Hello world!")
end
-- Zdalne wydarzenie z funkcją jako argument
remoteEvent:FireAllClients(testFunction)

Indeksowanie Tabel

Jeśli przeszesz tabelę danych, nie przeszesz mieszaną tabelę kluczy numerowych i literackich. Zamiast tego przeszesz tabelę, która składa się w całości pary kluczowe (słownik) lub w całości kluczowe indeksy.

Połączenie wątku - 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
--> CharName = Diva Dragonslayer
--> CharClass = Rogue
end
end
-- Połącz funkcję z wydarzeniem
remoteEvent.OnServerEvent:Connect(onEventFire)
Wydarzenie - Lokalny Skrypt

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Liczbowo z索wana tabela
local inventoryData = {
"Sword", "Bow"
}
-- Tabela słownika
local characterData = {
CharName = "Diva Dragonslayer",
CharClass = "Rogue"
}
remoteEvent:FireServer(inventoryData)
remoteEvent:FireServer(characterData)

Tożsamość tabeli

Tabele przesłane jako argumenty do zdalnych wydarzeń/zwrotów klamer są kopiowane, co oznacza, że nie będą dokładnie równoważne z tymi dostarczanymi podczas uruchamiania wydarzenia lub wzywania zwrotu klamer. Nie zostaną one również zwrócone do wskazanego przez wskazującego, co można zrobić poprzez uruchomienie następującego skryptu na RemoteFunction

Callback połączenie - Skrypt

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Funkcja zwrotu
local function returnTable(player, passedTable)
-- Wyświetl tożsamość tabeli przy wezwaniu
print(tostring(passedTable)) --> tabela: 0x48eb7aead27563d9
return passedTable
end
-- Ustaw funkcję jako wzwanie funkcji zdalnej
remoteFunction.OnServerInvoke = returnTable
Wyzwanie wydarzenia - Lokalny Skrypt

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
local inventoryData = {
"Sword", "Bow"
}
-- Wyświetl oryginalną tożsamość tabeli
print(tostring(inventoryData)) --> tabela: 0x059bcdbb2b576549
local invokeReturn = remoteFunction:InvokeServer(inventoryData)
-- Wyświetl tożsamość tabeli przy powrocie
print(tostring(invokeReturn)) --> table: 0x9fcae7919563a0e9

Metatabela

Jeśli tabela ma metabelę, wszystkie informacje o metabeli w przekazie zostaną stracone. W następnym przykładzie kodu właściwość NumWheels jest częścią metabeli Car. Gdy serwer otrzymuje następującą tabelę, właściwość

Połączenie wątku - 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)
Wydarzenie - Lokalny Skrypt

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)
-- Wydarzenie ognia z tabelą zawierającą metabelę
remoteEvent:FireServer(truck)

Niezależne instancje

Jeśli RemoteEvent lub RemoteFunction przesyła wartość, która jest widoczna tylko dla nadawcy, Roblox nie replikuje jej na całej granicy klient-serwer i przesyła nil z

Wydarzenie - Skrypt

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Zostanie otrzymany jako "nil", 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 stworzysz część w LocalScript i spróbujesz ją przesłać do Script, serwer zobaczy nil, ponieważ część nie jest replikowalna dla serwera.

Wydarzenie - Lokalny Skrypt

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Zostanie otrzymany jako "nil", ponieważ serwer nie wie o tej części
local clientPart = Instance.new("Part")
clientPart.Parent = workspace
remoteEvent:FireServer(clientPart)