BindableEvent و BindableFunction تتيح لك ربط السلوكيات بين السكربتات على نفس الجانب من حدود العميل والخادم والتواصل حول نتيجة معينة مرغوبة للعملية داخل اللعبة.
الاستخدام الأكثر شيوعًا للأحداث القابلة للتجميع هو للألعاب التي تحتوي على هيكل مبني على جولات. على سبيل المثال، قد يكون لديك حدث "بدأت المباراة" الذي يسمح للسكربتات الأخرى ببدء عداد و عرض لوحة المتصدرين، مع حدث "انتهت المباراة" المقابل الذي يسمح للسكربتات الأخرى بمعرفة متى يجب إعادة اللاعبين إلى قاعة الانتظار و عرض الفائزين.
نظرًا لأنها تنسق الأنشطة بين السكربتات، عادةً ما تستخدم الأحداث القابلة للتجميع على الخادم، ولكن يمكنك استخدامها أيضًا على العميل.
اعتمادًا على كيفية عمل لعبتك، يمكن أن تساعد الأحداث القابلة للتجميع في جعل الكود الخاص بك أكثر وحدة، ولكن سكريبتات الوحدة غالبًا ما تكون بديلًا أفضل في حالات تحتاج فيها إلى مشاركة البيانات بين السكربتات. يمكنك أيضًا استخدام الأحداث القابلة للتجميع بالاشتراك مع سكريبتات الوحدة للحصول على بناء جملة أنظف، كما هو موضح في الأحداث المخصصة.
الأحداث القابلة للتجميع
يسمح كائن BindableEvent بإنشاء أحداث مخصصة من خلال التواصل غير المتزامن باتجاه واحد بين السكربتات.
عندما تقوم بتشغيل BindableEvent من خلال طريقة Fire()، لا تتوقف السكربت الذي يتم تشغيله، وتتلقى الدالة المستهدفة المتغيرات المرسلة مع بعض القيود. مثل جميع الأحداث، تقوم BindableEvents بإنشاء خيوط لكل دالة متصلة، لذلك حتى إذا حدث خطأ في واحدة، تستمر الأخريات.
لإنشاء BindableEvent جديد باستخدام نافذة Explorer في الأستوديو:
- مرر فوق الحاوية التي تريد إدراج 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 في الأستوديو:
- مرر فوق الحاوية التي تريد إدراج 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، أو function، تقوم 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")-- إشعال الحدث مع جدول يحتوي على كائن workspace كقيمة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)