BindableEvent oraz BindableFunction pozwalają na powiązanie zachowań między skryptami po tej samej stronie granicy klient-serwer oraz komunikację określonego oczekiwanego wyniku działań w grze.
Najczęstszym przypadkiem użycia wydarzeń, które można powiązać, są gry o strukturze opartej na rundach. Na przykład możesz mieć wydarzenie "mecz rozpoczęty", które pozwala innym skryptom uruchomić stoper i wyświetlić wynik, a do tego odpowiadające mu wydarzenie "mecz zakończony", które informuje inne skrypty, kiedy należy przenieść graczy z powrotem do lobby oraz wyświetlić zwycięzców.
Ponieważ koordynują one działania między skryptami, wydarzenia, które można powiązać, są zazwyczaj używane na serwerze, ale możesz ich używać także po stronie klienta.
W zależności od tego, jak działa twoja gra, wydarzenia, które można powiązać, mogą pomóc w uczynieniu twojego kodu bardziej modularnym, ale skrypty modułowe często są lepszą alternatywą w sytuacjach, w których musisz dzielić się danymi między skryptami. Możesz także używać wydarzeń, które można powiązać, w połączeniu ze skryptami modułowymi dla bardziej przejrzystej składni, jak wspomniano w Wydarzeniach niestandardowych.
Wydarzenia, które można powiązać
Obiekt BindableEvent umożliwia tworzenie niestandardowych wydarzeń poprzez asynchroniczną, jednokierunkową komunikację między skryptami.
Gdy wyzwalasz BindableEvent za pomocą metody Fire(), skrypt wyzwalający nie przerywa działania, a funkcja docelowa otrzymuje przekazane argumenty z pewnymi ograniczeniami. Jak wszystkie wydarzenia, BindableEvents tworzy wątki dla każdej podłączonej funkcji, więc nawet jeśli jedna napotka błąd, inne będą kontynuować.
Aby utworzyć nowe BindableEvent za pomocą okna Eksploratora w Studio:
- Najedź kursorem na kontener, do którego chcesz wstawić BindableEvent. Zalecamy użycie ServerScriptService do komunikacji między skryptami serwera oraz ReplicatedStorage do komunikacji między skryptami klienta.
- Kliknij przycisk ⊕, który pojawia się po prawej stronie nazwy kontenera i wstaw instancję BindableEvent.
- Zmień nazwę instancji na TestBindableEvent.
Gdy już utworzysz BindableEvent, podłącz funkcję do jej wydarzenia Event w jednym skrypcie, a następnie wyzwól Fire() wydarzenie z innego skryptu.
Podłączenie Wydarzenia
local ServerScriptService = game:GetService("ServerScriptService")
-- Uzyskaj odniesienie do instancji bindable event
local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")
-- Podłącz funkcję anonimową do wydarzenia
bindableEvent.Event:Connect(function(data)
print(data) --> Runda rozpoczęta!
end)
Wyzwalanie Wydarzenialocal ServerScriptService = game:GetService("ServerScriptService")-- Uzyskaj odniesienie do instancji bindable eventlocal bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")-- Wyzwól bindable eventbindableEvent:Fire("Runda rozpoczęta!")
Niestandardowe wywołania zwrotne
Obiekt BindableFunction pozwala na synchroniczną, dwukierunkową komunikację między skryptami. Możesz go użyć do zdefiniowania niestandardowej funkcji wywołania zwrotnego i wywołania jej ręcznie, wywołując BindableFunction:Invoke(). Kod wywołujący funkcję wstrzymuje działanie do momentu, gdy odpowiadające wywołanie zwrotne zostanie znalezione, a wywołanie zwrotne otrzymuje argumenty, które przekazałeś do Invoke(). Jeśli wywołanie zwrotne nigdy nie zostało ustawione, skrypt, który je wywołuje, nie wznawia wykonania.
Aby utworzyć nowe BindableFunction za pomocą okna Eksploratora w Studio:
- Najedź kursorem na kontener, do którego chcesz wstawić BindableFunction. Zalecamy użycie ServerScriptService do komunikacji między skryptami serwera oraz ReplicatedStorage do komunikacji między skryptami klienta.
- Kliknij przycisk ⊕, który pojawia się po prawej stronie nazwy kontenera i wstaw instancję BindableFunction.
- Zmień nazwę instancji na TestBindableFunction.
Gdy już utworzysz BindableFunction, możesz połączyć się z jego wywołaniem zwrotnym OnInvoke w jednym skrypcie, a następnie wywołać funkcję wywołania zwrotnego z innego skryptu za pomocą Invoke().
Podłączenie Wywołania Zwrotnego
local ServerScriptService = game:GetService("ServerScriptService")
-- Uzyskaj odniesienie do podręcznej funkcji
local bindableFunction = ServerScriptService:WaitForChild("TestBindableFunction")
-- Funkcja wywołania zwrotnego
local function addTwoNumbers(a, b)
return a + b
end
-- Ustaw funkcję jako wywołanie zwrotne bindable function
bindableFunction.OnInvoke = addTwoNumbers
Wywołanie Wydarzenialocal ServerScriptService = game:GetService("ServerScriptService")-- Uzyskaj odniesienie do podręcznej funkcjilocal bindableFunction = ServerScriptService:WaitForChild("TestBindableFunction")-- Wywołaj funkcję wywołania zwrotnego i wypisz wartość zwróconąlocal sum = bindableFunction:Invoke(2, 4)print(sum) --> 6
Ograniczenia argumentów
Gdy wyzwalasz BindableEvent lub wywołujesz BindableFunction, przekazuje on dowolne argumenty, które przekazujesz z wydarzeniem lub do funkcji wywołania zwrotnego. Możesz przekazać dowolny typ obiektu Roblox (Enum, Instance itp.), a także typy Luau, takie jak liczby, ciągi znaków i wartości logiczne, chociaż musisz ostrożnie rozważyć następujące ograniczenia.
Indeksy, które nie są ciągami
Jeśli jakiekolwiek indeksy przekazanej tabeli są typami, które nie są ciągami, takimi jak Instance, userdata lub funkcje, Roblox automatycznie konwertuje te indeksy na ciągi.
Podłączenie Wydarzenia
local ServerScriptService = game:GetService("ServerScriptService")
local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")
local function onEventFire(passedTable)
for k, v in passedTable do
print(typeof(k)) --> string
end
end
-- Podłącz funkcję do wydarzenia
bindableEvent.Event:Connect(onEventFire)
Wyzwalanie Wydarzenialocal ServerScriptService = game:GetService("ServerScriptService")local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")-- Wyzwól wydarzenie z tabelą zawierającą instancję z workspace jako kluczbindableEvent:Fire({[workspace.Baseplate] = true})
Indeksowanie tabel
Jeśli przekazujesz tabelę danych, nie przekazuj mieszanej tabeli z kluczami numerycznymi i ciągłymi. Może to spowodować usunięcie elementów podczas transferu. Zamiast tego przekazuj tabelę składającą się wyłącznie z par klucz-wartość (słownik) lub wyłącznie z indeksów numerycznych (tabliczka).
Podłączenie Wydarzenia
local ServerScriptService = game:GetService("ServerScriptService")
local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")
local function onEventFire(passedTable)
for k, v in passedTable do
print(k .. " = " .. v)
--> 1 = Miecz
--> 2 = Łuk
--> CharName = Diva Dragonslayer
--> CharClass = Rogue
end
end
-- Podłącz funkcję do wydarzenia
bindableEvent.Event:Connect(onEventFire)
Wyzwalanie Wydarzenialocal ServerScriptService = game:GetService("ServerScriptService")local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")-- Tablica o indeksach numerycznychlocal inventoryData = {"Miecz", "Łuk"}-- Tabela słowniklocal characterData = {CharName = "Diva Dragonslayer",CharClass = "Rogue"}-- Wyzwól wydarzenie z tabelami o spójnym indeksiebindableEvent:Fire(inventoryData)bindableEvent:Fire(characterData)
Tożsamości tabel
Tabele przekazywane jako argumenty do wydarzeń, które można powiązać, i wywołań zwrotnych są kopiowane, co oznacza, że nie będą dokładnie równoważne tym, jakie zostały przekazane podczas wyzwalania wydarzenia lub wywoływania wywołania zwrotnego. Tabele zwracane do wywołującego również nie będą dokładnie równoważne tym, jakie zostały udostępnione. Możesz to zilustrować, uruchamiając następujący skrypt na BindableFunction i obserwując, jak różnią się tożsamości tabel.
Podłączenie Wywołania Zwrotnego
local ServerScriptService = game:GetService("ServerScriptService")
local bindableFunction = ServerScriptService:WaitForChild("TestBindableFunction")
-- Funkcja wywołania zwrotnego
local function returnTable(passedTable)
-- Wypisz tożsamość tabeli podczas wywołania
print(tostring(passedTable)) --> table: 0x48eb7aead27563d9
return passedTable
end
-- Ustaw funkcję jako wywołanie zwrotne bindable function
bindableFunction.OnInvoke = returnTable
Wywołanie Wydarzenialocal ServerScriptService = game:GetService("ServerScriptService")local bindableFunction = ServerScriptService:WaitForChild("TestBindableFunction")local inventoryData = {"Miecz", "Łuk"}-- Wypisz oryginalną tożsamość tabeliprint(tostring(inventoryData)) --> table: 0x059bcdbb2b576549local invokeReturn = bindableFunction:Invoke(inventoryData)-- Wypisz tożsamość tabeli po zwrocieprint(tostring(invokeReturn)) --> table: 0x9fcae7919563a0e9
Metatabele
Jeśli tabela ma metatabelę, wszystkie informacje o metatabelach są tracone podczas transferu. W poniższym przykładzie kodu, właściwość NumWheels jest częścią metatabeli Car. Gdy serwer odbierze poniższą tabelę, tabela truck ma właściwość Name, ale nie ma właściwości NumWheels.
Podłączenie Wydarzenia
local ServerScriptService = game:GetService("ServerScriptService")
local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")
local function onEvent(param)
print(param) --> {["Name"] = "MyTruck"}
end
-- Podłącz funkcję do wydarzenia
bindableEvent.Event:Connect(onEvent)
Wyzwalanie Wydarzenialocal ServerScriptService = game:GetService("ServerScriptService")local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")local Car = {}Car.NumWheels = 4Car.__index = Carlocal truck = {}truck.Name = "MyTruck"setmetatable(truck, Car)-- Wyzwól wydarzenie z tabelą zawierającą metatabelębindableEvent:Fire(truck)