可绑定的事件和回调

*此内容使用人工智能(Beta)翻译,可能包含错误。若要查看英文页面,请点按 此处

BindableEventBindableFunction 对象可让你在 同一侧客户端-服务器 边界之间绑定行为,并传达体验中的特定期望结果。

最常见的可绑定事件使用案例是那些具有回合结构的体验。例如,你可能会有一个“匹配开始”事件,其他脚本可以启动计时器并显示排行榜,具有相应的“匹配结束”事件,其他脚本可以知道何时将玩家移回大厅并显示获胜者。

因为它们协调脚本之间的活动,可绑定事件通常在服务器上使用,但您也可以在客户端上使用它们。

根据您的体验如何运行,可绑定的事件可以帮助使您的代码更具模块化,但 模块脚本 经常是在需要在脚本之间共享数据的情况下的更好选择。您还可以使用可绑定的事件与模块脚本结合,以获得更干净的语法,如在 自定义事件 中所述。

可绑定的事件

BindableEvent 对象通过异步、单向通信启用了自定义事件。

当你通过 方法发射一个 时,发射脚本不会产生,目标函数接收传递的参数受到某些限制 。与所有事件一样,BindableEvents 创建每个连接的函数的线程,即使出现一个错误,其他人也会继续。

要使用 Studio 中的 BindableEvent 窗口创建一个新的

  1. 将鼠标悬停在你想要插入 BindableEvent 的容器上。我们建议使用 ServerScriptService 来实现服务器脚本之间的通信,使用 ReplicatedStorage 来实现客户端脚本之间的通信。
  2. 点击容器名称右侧的 按钮,然后插入 可绑定事件 实例。
  3. 将实例重命名为 TestBindableEvent

在你创建了一个 之后,在一个脚本中连接一个函数到其 事件,然后从另一个脚本中获取事件。

事件连接

local ServerScriptService = game:GetService("ServerScriptService")
-- 获取可绑定的事件实例的参考
local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")
-- 将匿名函数连接到事件
bindableEvent.Event:Connect(function(data)
print(data) --> 回合开始了!
end)
事件发射

local ServerScriptService = game:GetService("ServerScriptService")
-- 获取可绑定的事件实例的参考
local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")
-- 火焰可绑定事件
bindableEvent:Fire("Round started!")

自定义回调

BindableFunction 对象允许脚本之间的同步、双向通信。您可以使用它来定义自定义回调函数,并通过调用 BindableFunction:Invoke() 手动调用它。调用函数 的代码直到找到相应的回调,并接收你传给 的参数才会产生 。如果回调从未设置,触发它的脚本不会恢复执行。

要使用 Studio 中的 BindableFunction 窗口创建一个新的

  1. 将鼠标悬停在你想要插入 BindableFunction 的容器上。我们建议使用 ServerScriptService 来实现服务器脚本之间的通信,使用 ReplicatedStorage 来实现客户端脚本之间的通信。
  2. 点击容器名称右侧的 按钮,然后插入 可绑定函数实例
  3. 将实例重命名为 TestBindableFunction

一旦你创建了一个 ,你可以在一个脚本中连接到其 回调,然后在另一个脚本中连接回调函数。

回调连接

local ServerScriptService = game:GetService("ServerScriptService")
-- 获取可绑定的函数的参考
local bindableFunction = ServerScriptService:WaitForChild("TestBindableFunction")
-- 回调函数
local function addTwoNumbers(a, b)
return a + b
end
-- 将函数设置为可绑定的函数的回调
bindableFunction.OnInvoke = addTwoNumbers
事件邀请

local ServerScriptService = game:GetService("ServerScriptService")
-- 获取可绑定的函数的参考
local bindableFunction = ServerScriptService:WaitForChild("TestBindableFunction")
-- 调用回调函数并返回输出值
local sum = bindableFunction:Invoke(2, 4)
print(sum) --> 6

论据限制

当你发射一个 BindableEvent 或调用一个 BindableFunction 时,它会将你通过事件或调用回调函数传递的任何参数转发到前方。您可以传递任何类型的 Roblox 对象(Enum , Instance ,等),以及像数字、字符串和布尔一样的 Luau 类型,但您应该仔细考虑以下限制。

非字符索引

如果传递的表中的任何 索引 为非字符型,例如 Instanceuserdata函数,Roblox 将自动将这些索引转换为字符串。

事件连接

local ServerScriptService = game:GetService("ServerScriptService")
local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")
local function onEventFire(passedTable)
for k, v in passedTable do
print(typeof(k)) --> 字符串
end
end
-- 将连接函数连接到事件
bindableEvent.Event:Connect(onEventFire)
事件发射

local ServerScriptService = game:GetService("ServerScriptService")
local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")
-- 包含工作区实例的键的火事件
bindableEvent:Fire({
[workspace.Baseplate] = true
})

表索引化

如果你通过数据表,不要通过混合的数字和字符串键表。相反,传递包含 全部 键值对 (一个词典) 或 全部 数字索引 (一个阵数组) 的表。

事件连接

local ServerScriptService = game:GetService("ServerScriptService")
local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")
local function onEventFire(passedTable)
for k, v in passedTable do
print(k .. " = " .. v)
-->1=剑
--> 2 = 弓
--> 角色名称 = 迪瓦龙杀手
--> 字符类 = 恶行
end
end
-- 将连接函数连接到事件
bindableEvent.Event:Connect(onEventFire)
事件发射

local ServerScriptService = game:GetService("ServerScriptService")
local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")
-- 数字索引表
local inventoryData = {
"Sword", "Bow"
}
-- 词典表
local characterData = {
CharName = "Diva Dragonslayer",
CharClass = "Rogue"
}
-- 使用一致索引的表发射事件
bindableEvent:Fire(inventoryData)
bindableEvent:Fire(characterData)

表身份

传递到可绑定事件和回调的表作为参数的表被复制,这意味着它们不会与在发射事件或调用回调时提供的完全相等。被返回给调用者的表也不会与提供的表完全相等。您可以通过在 BindableFunction 上运行以下脚本来展示这一点,并观察表身份之间的差异。

回调连接

local ServerScriptService = game:GetService("ServerScriptService")
local bindableFunction = ServerScriptService:WaitForChild("TestBindableFunction")
-- 回调函数
local function returnTable(passedTable)
-- 在调用时输出表身份标识
print(tostring(passedTable)) --> 表:0x48eb7aead27563d9
return passedTable
end
-- 将函数设置为可绑定的函数的回调
bindableFunction.OnInvoke = returnTable
事件邀请

local ServerScriptService = game:GetService("ServerScriptService")
local bindableFunction = ServerScriptService:WaitForChild("TestBindableFunction")
local inventoryData = {
"Sword", "Bow"
}
-- 输出原始表身份
print(tostring(inventoryData)) --> 表:0x059bcdbb2b576549
local invokeReturn = bindableFunction:Invoke(inventoryData)
-- 返回传时输出表识别符
print(tostring(invokeReturn)) --> table: 0x9fcae7919563a0e9

元表

如果表有一个可转换字段,所有可转换信息在传输中丢失。在以下代码示例中,NumWheels 属性是 Car 可交换的一部分。当服务器收到以下表时,表 具有 属性,但不具有 属性。

事件连接

local ServerScriptService = game:GetService("ServerScriptService")
local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")
local function onEvent(param)
print(param) --> {["名称"] = "我的卡车"}
end
-- 将连接函数连接到事件
bindableEvent.Event:Connect(onEvent)
事件发射

local ServerScriptService = game:GetService("ServerScriptService")
local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")
local Car = {}
Car.NumWheels = 4
Car.__index = Car
local truck = {}
truck.Name = "MyTruck"
setmetatable(truck, Car)
-- 包含可转换表的火焰事件
bindableEvent:Fire(truck)