可绑定事件和回调

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

BindableEventBindableFunction 对象让您在 同一侧客户端-服务器 边界上绑定脚本之间的行为,并传达游戏内行动的特定期望结果。

可绑定事件的最常见用例是用于有回合结构的游戏。例如,您可能有一个“比赛开始”事件,让其他脚本启动计时器并显示排行榜,并有一个对应的“比赛结束”事件,让其他脚本知道何时将玩家带回大厅并显示获胜者。

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

根据您的游戏运作方式,可绑定事件可以帮助使您的代码更模块化,但是 模块脚本 通常是更好的选择,用于需要在脚本之间共享数据的情况。您还可以结合模块脚本使用可绑定事件,以获得更简洁的语法,如 自定义事件 中所述。

可绑定事件

BindableEvent 对象通过脚本之间的异步单向通信启用自定义事件。

当您通过 Fire() 方法触发 BindableEvent 时,触发的脚本 不会 阻塞,而目标函数会接收传递的参数,具有某些 限制。像所有事件一样,BindableEvents 创建了每个连接函数的线程,因此即使其中一个发生错误,其他线程也会继续执行。

要使用 Studio 中的 资源管理器 窗口创建新的 BindableEvent

  1. 将鼠标悬停在您要插入 BindableEvent 的容器上。我们建议使用 ServerScriptService 进行服务器脚本之间的通信,使用 ReplicatedStorage 进行客户端脚本之间的通信。
  2. 点击出现在容器名称右侧的 按钮,并插入一个 BindableEvent 实例。
  3. 将实例重命名为 TestBindableEvent

创建 BindableEvent 后,在一个脚本中连接一个函数到它的 Event 事件,然后在另一个脚本中 Fire() 该事件。

事件连接

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("回合开始!")

自定义回调

BindableFunction 对象允许脚本之间的同步双向通信。您可以使用它定义自定义回调函数,并通过调用 BindableFunction:Invoke() 手动调用该函数。调用该函数的代码 会阻塞,直到找到对应的回调为止,而回调会接收您传递给 Invoke() 的参数。如果从未设置回调,调用它的脚本将不会恢复执行。

要使用 Studio 中的 资源管理器 窗口创建新的 BindableFunction

  1. 将鼠标悬停在您要插入 BindableFunction 的容器上。我们建议使用 ServerScriptService 进行服务器脚本之间的通信,使用 ReplicatedStorage 进行客户端脚本之间的通信。
  2. 点击出现在容器名称右侧的 按钮,并插入一个 BindableFunction 实例。
  3. 将实例重命名为 TestBindableFunction

创建 BindableFunction 后,您可以在一个脚本中连接到它的 OnInvoke 回调,然后从另一个脚本中 Invoke() 回调函数。

回调连接

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 对象(EnumInstance 等),以及 Luau 类型,如数字、字符串和布尔值,但您应该仔细考虑以下限制。

非字符串索引

如果传递的表的任何 索引 是非字符串类型,例如 Instanceuserdatafunction,Roblox 会自动将这些索引转换为字符串。

事件连接

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
-- 将函数连接到事件
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 = 弓
--> CharName = Diva Dragonslayer
--> CharClass = Rogue
end
end
-- 将函数连接到事件
bindableEvent.Event:Connect(onEventFire)
事件触发

local ServerScriptService = game:GetService("ServerScriptService")
local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")
-- 数字索引表
local inventoryData = {
"剑", "弓"
}
-- 字典表
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)) --> table: 0x48eb7aead27563d9
return passedTable
end
-- 将函数设置为可绑定函数的回调
bindableFunction.OnInvoke = returnTable
事件调用

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

元表

如果一个表有元表,所有的元表信息在传输中都会丢失。在以下代码示例中,NumWheels 属性是 Car 元表的一部分。当服务器接收到以下表时,truck 表具有 Name 属性,但 没有 NumWheels 属性。

事件连接

local ServerScriptService = game:GetService("ServerScriptService")
local bindableEvent = ServerScriptService:WaitForChild("TestBindableEvent")
local function onEvent(param)
print(param) --> {["Name"] = "MyTruck"}
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)
©2026 Roblox Corporation、Roblox、Roblox 标志及 Powering Imagination 是我们在美国及其他国家或地区的注册与未注册商标。