BindableEvent e BindableFunction ti permettono di legare comportamenti tra script sullo stesso lato del confine client-server e comunicare un risultato desiderato specifico per le azioni in gioco.
Il caso d'uso più comune per gli eventi bindabili è per i giochi che hanno una struttura a turni. Ad esempio, potresti avere un evento "partita iniziata" che consente ad altri script di avviare un timer e visualizzare una classifica, con un corrispondente evento "partita finita" che consente ad altri script di sapere quando spostare i giocatori di nuovo in un lounge e visualizzare i vincitori.
Poiché coordinano le attività tra script, gli eventi bindabili sono tipicamente utilizzati sul server, ma puoi usarli anche sul client.
A seconda di come funziona il tuo gioco, gli eventi bindabili possono aiutare a rendere il tuo codice più modulare, ma gli script di modulo sono spesso un'alternativa migliore per situazioni in cui hai bisogno di condividere dati tra script. Puoi anche utilizzare eventi bindabili insieme a script di modulo per una sintassi più pulita, come notato in Eventi personalizzati.
Eventi bindabili
L'oggetto BindableEvent abilita eventi personalizzati attraverso la comunicazione asincrona, unidirezionale tra script.
Quando attivi un BindableEvent tramite il metodo Fire(), lo script che attiva non cede, e la funzione di destinazione riceve gli argomenti passed con alcune limitazioni. Come tutti gli eventi, BindableEvents creano thread per ciascuna funzione connessa, quindi anche se una dà errore, le altre continuano.
Per creare un nuovo BindableEvent usando la finestra Explorer in Studio:
- Passa sopra il contenitore nel quale vuoi inserire il BindableEvent. Ti consigliamo di usare ServerScriptService per la comunicazione tra script server e ReplicatedStorage per la comunicazione tra script client.
- Clicca sul pulsante ⊕ che appare a destra del nome del contenitore e inserisci un'istanza BindableEvent.
- Rinomina l'istanza in TestBindableEvent.
Dopo aver creato un BindableEvent, collega una funzione al suo evento Event in uno script, e poi Fire() l'evento da un altro script.
Connessione Evento
local ServerScriptService = game:GetService("ServerScriptService")
-- Ottieni riferimento all'istanza dell'evento bindabile
local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")
-- Collega una funzione anonima all'evento
bindableEvent.Event:Connect(function(data)
print(data) --> Turno iniziato!
end)
Attivazione Eventolocal ServerScriptService = game:GetService("ServerScriptService")-- Ottieni riferimento all'istanza dell'evento bindabilelocal bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")-- Attiva l'evento bindabilebindableEvent:Fire("Turno iniziato!")
Callback personalizzati
L'oggetto BindableFunction consente una comunicazione sincrona, bidirezionale tra script. Puoi usarlo per definire una funzione di callback personalizzata e invocarla manualmente chiamando BindableFunction:Invoke(). Il codice che invoca la funzione cede fino a quando la corrispondente callback non viene trovata, e la callback riceve gli argomenti che hai passato a Invoke(). Se la callback non è mai stata impostata, lo script che la invoca non riprende l'esecuzione.
Per creare un nuovo BindableFunction usando la finestra Explorer in Studio:
- Passa sopra il contenitore nel quale vuoi inserire il BindableFunction. Ti consigliamo di usare ServerScriptService per la comunicazione tra script server e ReplicatedStorage per la comunicazione tra script client.
- Clicca sul pulsante ⊕ che appare a destra del nome del contenitore e inserisci un'istanza BindableFunction.
- Rinomina l'istanza in TestBindableFunction.
Una volta creato un BindableFunction, puoi collegarti al suo callback OnInvoke in uno script, poi Invoke() la funzione di callback da un altro script.
Connessione Callback
local ServerScriptService = game:GetService("ServerScriptService")
-- Ottieni riferimento alla funzione bindabile
local bindableFunction = ServerScriptService:WaitForChild("TestBindableFunction")
-- Funzione di callback
local function addTwoNumbers(a, b)
return a + b
end
-- Imposta la funzione come callback della funzione bindabile
bindableFunction.OnInvoke = addTwoNumbers
Invocazione Eventolocal ServerScriptService = game:GetService("ServerScriptService")-- Ottieni riferimento alla funzione bindabilelocal bindableFunction = ServerScriptService:WaitForChild("TestBindableFunction")-- Invoca la funzione di callback e output del valore restituitolocal sum = bindableFunction:Invoke(2, 4)print(sum) --> 6
Limitazioni degli argomenti
Quando attivi un BindableEvent o invochi un BindableFunction, esso inoltra qualsiasi argomento che passi con l'evento o alla funzione di callback. Puoi passare qualsiasi tipo di oggetto Roblox (Enum, Instance, ecc.), così come tipi Luau come numeri, stringhe e booleani, anche se dovresti considerare attentamente le seguenti limitazioni.
Indici non stringa
Se qualche indice di una tabella passata è di tipo non stringa, come un Instance, userdata o funzione, Roblox converte automaticamente quegli indici in stringhe.
Connessione Evento
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
-- Collega la funzione all'evento
bindableEvent.Event:Connect(onEventFire)
Attivazione Eventolocal ServerScriptService = game:GetService("ServerScriptService")local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")-- Attiva l'evento con una tabella contenente un'istanza di workspace come chiavebindableEvent:Fire({[workspace.Baseplate] = true})
Indicizzazione della tabella
Se passi una tabella di dati, non passare una tabella mista di chiavi numeriche e stringa. Farlo può risultare in elementi rimossi durante il trasferimento. Invece, passa una tabella che consiste interamente di coppie chiave-valore (un dizionario) o interamente di indici numerici (un array).
Connessione Evento
local ServerScriptService = game:GetService("ServerScriptService")
local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")
local function onEventFire(passedTable)
for k, v in passedTable do
print(k .. " = " .. v)
--> 1 = Spada
--> 2 = Arco
--> CharName = Diva Dragonslayer
--> CharClass = Rogue
end
end
-- Collega la funzione all'evento
bindableEvent.Event:Connect(onEventFire)
Attivazione Eventolocal ServerScriptService = game:GetService("ServerScriptService")local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")-- Tabella indicizzata numericamentelocal inventoryData = {"Spada", "Arco"}-- Tabella dizionariolocal characterData = {CharName = "Diva Dragonslayer",CharClass = "Rogue"}-- Attiva l'evento con tabelle indicizzate in modo coerentebindableEvent:Fire(inventoryData)bindableEvent:Fire(characterData)
Identità delle tabelle
Le tabelle passate come argomenti a eventi bindabili e callback vengono copiate, il che significa che non saranno esattamente equivalenti a quelle fornite durante l'attivazione dell'evento o l'invocazione della callback. Né le tabelle restituite all'invocatore saranno esattamente equivalenti a quelle fornite. Puoi dimostrare questo eseguendo il seguente script su un BindableFunction e osservando come le identità delle tabelle differiscano.
Connessione Callback
local ServerScriptService = game:GetService("ServerScriptService")
local bindableFunction = ServerScriptService:WaitForChild("TestBindableFunction")
-- Funzione di callback
local function returnTable(passedTable)
-- Output dell'identità della tabella all'invocazione
print(tostring(passedTable)) --> table: 0x48eb7aead27563d9
return passedTable
end
-- Imposta la funzione come callback della funzione bindabile
bindableFunction.OnInvoke = returnTable
Invocazione Eventolocal ServerScriptService = game:GetService("ServerScriptService")local bindableFunction = ServerScriptService:WaitForChild("TestBindableFunction")local inventoryData = {"Spada", "Arco"}-- Output dell'identità della tabella originaleprint(tostring(inventoryData)) --> table: 0x059bcdbb2b576549local invokeReturn = bindableFunction:Invoke(inventoryData)-- Output dell'identità della tabella al momento del ritornoprint(tostring(invokeReturn)) --> table: 0x9fcae7919563a0e9
Metatabelle
Se una tabella ha una metatabella, tutte le informazioni della metatabella vengono perse durante il trasferimento. Nell'esempio di codice seguente, la proprietà NumWheels fa parte della metatabella Car. Quando il server riceve la seguente tabella, la tabella truck ha la proprietà Name ma non la proprietà NumWheels.
Connessione Evento
local ServerScriptService = game:GetService("ServerScriptService")
local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")
local function onEvent(param)
print(param) --> {["Nome"] = "MyTruck"}
end
-- Collega la funzione all'evento
bindableEvent.Event:Connect(onEvent)
Attivazione Eventolocal ServerScriptService = game:GetService("ServerScriptService")local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")local Car = {}Car.NumWheels = 4Car.__index = Carlocal truck = {}truck.Name = "MyTruck"setmetatable(truck, Car)-- Attiva l'evento con una tabella che include una metatabellabindableEvent:Fire(truck)