BindableEvent et BindableFunction vous permettent de lier des comportements entre des scripts du même côté de la frontière client-serveur et de communiquer un résultat spécifique souhaité pour les actions dans le jeu.
Le cas d'utilisation le plus courant des événements bindables est pour les jeux qui ont une structure basée sur des tours. Par exemple, vous pourriez avoir un événement "match commencé" qui permet à d'autres scripts de démarrer un chronomètre et d'afficher un tableau de bord, avec un événement correspondant "match terminé" qui informe les autres scripts de renvoyer les joueurs dans un lobby et d'afficher les gagnants.
Parce qu'ils coordonnent les activités entre les scripts, les événements bindables sont généralement utilisés sur le serveur, mais vous pouvez aussi les utiliser sur le client.
En fonction du fonctionnement de votre jeu, les événements bindables peuvent aider à rendre votre code plus modulaire, mais les scripts de module sont souvent une meilleure alternative pour les situations où vous devez partager des données entre des scripts. Vous pouvez également utiliser des événements bindables en conjonction avec des scripts de module pour une syntaxe plus claire, comme indiqué dans Événements personnalisés.
Événements bindables
L'objet BindableEvent permet d'activer des événements personnalisés via une communication asynchrone, unidirectionnelle entre les scripts.
Lorsque vous déclenchez un BindableEvent via la méthode Fire(), le script déclencheur ne se met pas en attente, et la fonction cible reçoit les arguments passés avec certaines limitations. Comme tous les événements, BindableEvents créent des threads de chaque fonction connectée, donc même si l'une échoue, les autres continuent.
Pour créer un nouvel BindableEvent en utilisant la fenêtre Explorateur dans Studio :
- Survolez le conteneur dans lequel vous souhaitez insérer le BindableEvent. Nous recommandons d'utiliser ServerScriptService pour la communication entre les scripts du serveur et ReplicatedStorage pour la communication entre les scripts clients.
- Cliquez sur le bouton ⊕ qui apparaît à droite du nom du conteneur et insérez une instance BindableEvent.
- Renommez l'instance en TestBindableEvent.
Après avoir créé un BindableEvent, connectez une fonction à son événement Event dans un script, puis Fire() l'événement depuis un autre script.
Connexion d'Événement
local ServerScriptService = game:GetService("ServerScriptService")
-- Obtenir une référence à l'instance d'événement bindable
local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")
-- Connecter une fonction anonyme à l'événement
bindableEvent.Event:Connect(function(data)
print(data) --> Tour commencé !
end)
Tir d'Événementlocal ServerScriptService = game:GetService("ServerScriptService")-- Obtenir une référence à l'instance d'événement bindablelocal bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")-- Tirer l'événement bindablebindableEvent:Fire("Tour commencé !")
Rappels personnalisés
L'objet BindableFunction permet une communication synchrone, bidirectionnelle entre les scripts. Vous pouvez l'utiliser pour définir une fonction de rappel personnalisée et l'invoquer manuellement en appelant BindableFunction:Invoke(). Le code invoquant la fonction se met en attente jusqu'à ce que le rappel correspondant soit trouvé, et le rappel reçoit les arguments que vous avez passés à Invoke(). Si le rappel n'a jamais été défini, le script qui l'invoque ne reprend pas son exécution.
Pour créer un nouveau BindableFunction en utilisant la fenêtre Explorateur dans Studio :
- Survolez le conteneur dans lequel vous souhaitez insérer le BindableFunction. Nous recommandons d'utiliser ServerScriptService pour la communication entre les scripts du serveur et ReplicatedStorage pour la communication entre les scripts clients.
- Cliquez sur le bouton ⊕ qui apparaît à droite du nom du conteneur et insérez une instance BindableFunction.
- Renommez l'instance en TestBindableFunction.
Une fois que vous avez créé un BindableFunction, vous pouvez vous connecter à son rappel OnInvoke dans un script, puis Invoke() la fonction de rappel depuis un autre script.
Connexion de Rappel
local ServerScriptService = game:GetService("ServerScriptService")
-- Obtenir une référence à la fonction bindable
local bindableFunction = ServerScriptService:WaitForChild("TestBindableFunction")
-- Fonction de rappel
local function addTwoNumbers(a, b)
return a + b
end
-- Définir la fonction comme le rappel de la fonction bindable
bindableFunction.OnInvoke = addTwoNumbers
Invocation d'Événementlocal ServerScriptService = game:GetService("ServerScriptService")-- Obtenir une référence à la fonction bindablelocal bindableFunction = ServerScriptService:WaitForChild("TestBindableFunction")-- Invoquer la fonction de rappel et afficher la valeur retournéelocal sum = bindableFunction:Invoke(2, 4)print(sum) --> 6
Limitations des arguments
Lorsque vous déclenchez un BindableEvent ou invoquez un BindableFunction, il transmet tous les arguments que vous passez avec l'événement ou à la fonction de rappel. Vous pouvez passer n'importe quel type d'objet Roblox (Enum, Instance, etc.), ainsi que des types Luau tels que des nombres, des chaînes et des booléens, bien que vous deviez soigneusement considérer les limitations suivantes.
Indices non-chaînes
Si des indices d'une table passée sont des types non-chaînes, tels qu'une Instance, userdata, ou function, Roblox convertit automatiquement ces indices en chaînes.
Connexion d'Événement
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
-- Connecter la fonction à l'événement
bindableEvent.Event:Connect(onEventFire)
Tir d'Événementlocal ServerScriptService = game:GetService("ServerScriptService")local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")-- Tirer l'événement avec une table contenant une instance de workspace comme clébindableEvent:Fire({[workspace.Baseplate] = true})
Indexation de tables
Si vous passez une table de données, ne passez pas une table mixte avec des clés numériques et des clés de chaîne. Cela peut entraîner la suppression d'éléments pendant le transfert. Au lieu de cela, passez une table qui se compose entièrement de paires clé-valeur (un dictionnaire) ou entièrement d'indices numériques (un tableau).
Connexion d'Événement
local ServerScriptService = game:GetService("ServerScriptService")
local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")
local function onEventFire(passedTable)
for k, v in passedTable do
print(k .. " = " .. v)
--> 1 = Épée
--> 2 = Arc
--> CharName = Diva Dragonslayer
--> CharClass = Rogue
end
end
-- Connecter la fonction à l'événement
bindableEvent.Event:Connect(onEventFire)
Tir d'Événementlocal ServerScriptService = game:GetService("ServerScriptService")local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")-- Tableau indexé numériquementlocal inventoryData = {"Épée", "Arc"}-- Tableau de dictionnairelocal characterData = {CharName = "Diva Dragonslayer",CharClass = "Rogue"}-- Tirer l'événement avec des tables indexées de manière cohérentebindableEvent:Fire(inventoryData)bindableEvent:Fire(characterData)
Identités de tables
Les tables passées en tant qu'arguments à des événements bindables et des rappels sont copiées, ce qui signifie qu'elles ne seront pas exactement équivalentes à celles fournies lors du déclenchement de l'événement ou de l'invocation du rappel. De même, les tables retournées à l'appelant ne seront pas exactement équivalentes à celles fournies. Vous pouvez le démontrer en exécutant le script suivant sur un BindableFunction et en observant comment les identités de tables diffèrent.
Connexion de Rappel
local ServerScriptService = game:GetService("ServerScriptService")
local bindableFunction = ServerScriptService:WaitForChild("TestBindableFunction")
-- Fonction de rappel
local function returnTable(passedTable)
-- Afficher l'identité de la table lors de l'invocation
print(tostring(passedTable)) --> table: 0x48eb7aead27563d9
return passedTable
end
-- Définir la fonction comme le rappel de la fonction bindable
bindableFunction.OnInvoke = returnTable
Invocation d'Événementlocal ServerScriptService = game:GetService("ServerScriptService")local bindableFunction = ServerScriptService:WaitForChild("TestBindableFunction")local inventoryData = {"Épée", "Arc"}-- Afficher l'identité de la table d'origineprint(tostring(inventoryData)) --> table: 0x059bcdbb2b576549local invokeReturn = bindableFunction:Invoke(inventoryData)-- Afficher l'identité de la table lors du retourprint(tostring(invokeReturn)) --> table: 0x9fcae7919563a0e9
Métatables
Si une table a une métatable, toutes les informations de métatable sont perdues lors du transfert. Dans l'exemple de code suivant, la propriété NumWheels fait partie de la métatable Car. Lorsque le serveur reçoit la table suivante, la table truck a la propriété Name mais pas la propriété NumWheels.
Connexion d'Événement
local ServerScriptService = game:GetService("ServerScriptService")
local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")
local function onEvent(param)
print(param) --> {["Name"] = "MyTruck"}
end
-- Connecter la fonction à l'événement
bindableEvent.Event:Connect(onEvent)
Tir d'Événementlocal ServerScriptService = game:GetService("ServerScriptService")local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")local Car = {}Car.NumWheels = 4Car.__index = Carlocal truck = {}truck.Name = "MyTruck"setmetatable(truck, Car)-- Tirer l'événement avec une table incluant une métatablebindableEvent:Fire(truck)