BindableEvent และ BindableFunction ช่วยให้คุณผูกพฤติกรรมระหว่างสคริปต์ ในด้านเดียวกัน ของขอบเขต คลังเซิร์ฟเวอร์ และสื่อสารผลลัพธ์ที่ต้องการสำหรับการกระทำภายในเกม
กรณีการใช้งานที่พบบ่อยที่สุดสำหรับอีเวนต์ที่สามารถผูกคือสำหรับเกมที่มีโครงสร้างที่มีรอบ ตัวอย่างเช่น คุณอาจมีอีเวนต์ "เริ่มการแข่งขัน" ที่ช่วยให้สคริปต์อื่นเริ่มต้นนับเวลาและแสดงตารางผู้นำ พร้อมกับอีเวนต์ "จบการแข่งขัน" ที่ช่วยให้สคริปต์อื่นทราบเมื่อใดควรย้ายผู้เล่นกลับไปยังล็อบบี้และแสดงผู้ชนะ
เนื่องจากอีเวนต์ที่สามารถผูกจะทำหน้าที่ประสานกิจกรรมระหว่างสคริปต์ จึงมักใช้บนเซิร์ฟเวอร์ แต่คุณก็สามารถใช้ได้บนคลังเซิร์ฟเวอร์ด้วยเช่นกัน
ขึ้นอยู่กับว่าเกมของคุณทำงานอย่างไร อีเวนต์ที่สามารถผูกช่วยทำให้โค้ดของคุณมีความเป็นโมดูลาร์มากขึ้น แต่ โมดูลสคริปต์ มักเป็นทางเลือกที่ดีกว่าสำหรับสถานการณ์ที่คุณต้องการแชร์ข้อมูลระหว่างสคริปต์ คุณยังสามารถใช้ร่วมกับโมดูลสคริปต์เพื่อให้มีรูปแบบที่สะอาดขึ้น ตามที่กล่าวไว้ใน อีเวนต์ที่กำหนดเอง
อีเวนต์ที่สามารถผูก
ออบเจ็กต์ BindableEvent ช่วยให้มีอีเวนต์ที่กำหนดเองผ่านการสื่อสารแบบอะซิงโครนัสแบบทางเดียวระหว่างสคริปต์
เมื่อคุณเรียก BindableEvent ด้วยวิธีการ Fire() สคริปต์ที่เรียกจะ ไม่ หยุดทำงาน และฟังก์ชันเป้าหมายจะได้รับอาร์กิวเมนต์ที่ส่งผ่านไปพร้อมกับข้อจำกัดบางประการ ข้อจำกัดของอาร์กิวเมนต์ เช่นเดียวกับอีเวนต์ทั้งหมด BindableEvents สร้างเธรดของฟังก์ชันที่เชื่อมต่อกันแต่ละฟังก์ชัน ดังนั้นแม้ว่าฟังก์ชันหนึ่งจะเกิดข้อผิดพลาด ฟังก์ชันอื่น ๆ ยังคงดำเนินต่อไป
ในการสร้าง BindableEvent ใหม่โดยใช้หน้าต่าง Explorer ใน Studio:
- เลื่อนเมาส์ไปที่คอนเทนเนอร์ที่คุณต้องการแทรก BindableEvent เราขอแนะนำให้ใช้ ServerScriptService สำหรับการสื่อสารระหว่างสคริปต์เซิร์ฟเวอร์และ ReplicatedStorage สำหรับการสื่อสารระหว่างสคริปต์บนคลัง
- คลิกที่ปุ่ม ⊕ ที่ปรากฏทางด้านขวาของชื่อคอนเทนเนอร์และแทรกอินสแตนซ์ BindableEvent
- เปลี่ยนชื่ออินสแตนซ์เป็น 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() หากฟังก์ชันเรียกกลับไม่เคยตั้งไว้ สคริปต์ที่เรียกฟังก์ชันจะไม่ดำเนินการต่อ
ในการสร้าง BindableFunction ใหม่โดยใช้หน้าต่าง Explorer ใน Studio:
- เลื่อนเมาส์ไปที่คอนเทนเนอร์ที่คุณต้องการแทรก BindableFunction เราขอแนะนำให้ใช้ ServerScriptService สำหรับการสื่อสารระหว่างสคริปต์เซิร์ฟเวอร์และ ReplicatedStorage สำหรับการสื่อสารระหว่างสคริปต์บนคลัง
- คลิกที่ปุ่ม ⊕ ที่ปรากฏทางด้านขวาของชื่อคอนเทนเนอร์และแทรกอินสแตนซ์ BindableFunction
- เปลี่ยนชื่ออินสแตนซ์เป็น 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 ใด ๆ (Enum, Instance เป็นต้น) รวมถึงประเภทของ Luau เช่น หมายเลข สตริง และบูลีน แม้ว่าคุณควรพิจารณาข้อจำกัดต่อไปนี้อย่างรอบคอบ
ดัชนีที่ไม่ใช่สตริง
หากมี ดัชนี ใด ๆ ของตารางที่ส่งผ่านไปเป็นประเภทที่ไม่ใช่สตริง เช่น Instance, userdata หรือ ฟังก์ชัน 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: 0x059bcdbb2b576549local 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 = 4Car.__index = Carlocal truck = {}truck.Name = "MyTruck"setmetatable(truck, Car)-- เรียกอีเวนต์ด้วยตารางที่รวมอยู่ในเมตาเทเบิลbindableEvent:Fire(truck)