تجعل الألعاب التفاعلية من الضروري غالبًا التلاعب بخصائص وسمات الكائنات:
الخصائص هي جزء من فئة الكائن. على سبيل المثال، خاصية BasePart.Anchored تتحكم في الفيزياء للجزء. في لعبة ألعاب القوى، قد ترغب في تثبيت القرص أو الرمح في اللحظة التي يهبط فيها حتى يتمكن اللاعبون من الحصول على مؤشر مرئي لمدى بعده.
السمات هي في الأساس خصائص مخصصة تحددها. على سبيل المثال، يستخدم مشروع النبات المرجعي السمات لتحديد سعر الشراء للبذور وحجم النبات الأقصى الذي يمكن أن يحتفظ به وعاء.
ترتيب النسخ
قبل أن تبدأ في استرجاع والتلاعب بالكائنات، يجب أن يكون لديك فهم لترتيب النسخ.
لا يضمن محرك Roblox ترتيب النسخ للكائنات (والتغييرات على الكائنات) من الخادم إلى العميل، مما يجعل طريقة Instance:WaitForChild() أساسية للوصول إلى الكائنات في سكربتات العميل، وخاصة الكائنات في Workspace.
على سبيل المثال، إذا غيرت سكربت الخادم خاصية مثيل ما في Workspace ثم اتصل بـ RemoteEvent:FireAllClients()، قد تتكرر تغيير الخاصية إلى العميل قبل أو بعد تشغيل RemoteEvent.OnClientEvent. استخدم الطرق والأحداث المتاحة لت كشف التغييرات بدلاً من الافتراض أن التغيير تم نسخه. بشكل عام، تصل التغييرات من نفس النوع، مثل تغييرين في السمة، في العادة بترتيب.
عند بدء تشغيل العملاء للعبة لأول مرة، تكون بعض جوانب النسخ وتنفيذ السكربتات متوقعة:
يقوم العميل بتحميل محتويات ReplicatedFirst، مثل شاشة التحميل، والأصول، والسكربتات.
تعمل LocalScripts (و Scripts مع RunContext من Client) في ReplicatedFirst. يمكن لهذه السكربتات الحصول بأمان على الكائنات من ReplicatedFirst دون استخدام Instance:WaitForChild():
-- آمنlocal ReplicatedFirst = game:GetService("ReplicatedFirst")local LoadingScreen = require(ReplicatedFirst.LoadingScreen)لا يمكن لهذه السكربتات بأمان الحصول على كائنات من الخدمات الأخرى، لأنه قد يكون لم يتم تحميلها بعد:
-- ليس آمنًاlocal ReplicatedStorage = game:GetService("ReplicatedStorage")local PickupManager = require(ReplicatedStorage.PickupManager)يمكنك استخدام WaitForChild() في هذه السكربتات للحصول على كائنات من خدمات أخرى، ولكن القيام بذلك ينفي فوائد استخدام ReplicatedFirst.
يواصل العميل تحميل باقي اللعبة.
عند الانتهاء، يتلقى حدث Loaded وتعيد IsLoaded() القيمة true.
تعمل LocalScripts في Players.[Player].PlayerScripts (المحمولة من StarterPlayerScripts) بالإضافة إلى سكربتات العميل Scripts في ReplicatedStorage. يمكن لهذه السكربتات الحصول بأمان على الكائنات من ReplicatedStorage دون استخدام WaitForChild().
يتم استنساخ نموذج Character الخاص باللاعب في اللعبة.
تعمل LocalScripts في Workspace.[Character] (المحمولة من StarterCharacterScripts).
إذا كانت لعبتك تستخدم بث الكائنات (Workspace.StreamingEnabled)، فقد لا تكون بعض أو معظم الكائنات قد تم تحميلها في مساحة العمل، لذا يصبح استخدام WaitForChild() للوصول إلى كائنات مساحة العمل تدبير أمان أكثر أهمية. للحصول على معلومات إضافية حول تحميل وضبط سلوك البث، انظر إلى بث و تحكمات بث لكل نموذج.
الحصول على كائنات
الخطوة الأولى لتعديل خصائص وسمات الكائن هي الحصول على مرجع للعنصر. الحل الأكثر بساطة هو جعل السكربت طفلًا للكائن في المستعرض واستخدام script.Parent للإشارة إلى الكائن.

local sign = script.Parent
الحل الأكثر عمومية هو الحصول على الكائن من خدمة باستخدام طرق مثل Instance:FindFirstChild() أو Instance:WaitForChild().

local ReplicatedStorage = game:GetService("ReplicatedStorage")local signsFolder = ReplicatedStorage:WaitForChild("Signs")local sign = signsFolder:WaitForChild("InteractiveSign")
تعديل الخصائص
الخصائص من السهل الوصول إليها - فقط استخدم . بعد الإشارة إلى الكائن — على الرغم من أنه إذا كنت تعمل مع نموذج، قد تحتاج إلى اختيار جزء فردي بدلاً من النموذج نفسه.

local ReplicatedStorage = game:GetService("ReplicatedStorage")local chair = ReplicatedStorage:WaitForChild("Chair")chair.LeftArmRest.Size = Vector3.new(10, 1, 10)
إنشاء السمات
على الرغم من أنه يمكنك إنشاء السمات برمجيًا، فإن الحل الأكثر شيوعًا هو إنشاؤها بقيم افتراضية في واجهة المستخدم في الاستوديو. بعد ذلك، يمكنك استخدام السكربتات لتعديل قيمها استجابةً لأفعال اللاعبين.

للحصول على معلومات حول إنشاء السمات في الاستوديو، راجع سمات الكائنات.
ضبط السمات
لتعديل قيمة سمة، اتصل بـ Instance:SetAttribute() مع اسم وقيمة.
إنشاء أو تعديل سمةlocal cabbage = script.Parentcabbage:SetAttribute("Harvestable", true)
إذا لم تكن السمة موجودة بالفعل، فإن هذه الطريقة تقوم بإنشائها.
الحصول على قيم السمات
للحصول على قيمة سمة موجودة، اتصل بـ Instance:GetAttribute() على المثيل.
الحصول على قيمة السمةlocal cabbage = script.Parentcabbage:SetAttribute("Harvestable", true)local isHarvestable = cabbage:GetAttribute("Harvestable")print(isHarvestable) --> true
بالمثل، يمكنك الحصول على جميع السمات عن طريق استدعاء Instance:GetAttributes(). تُرجع هذه الطريقة قاموسًا من أزواج المفتاح والقيمة.
الحصول على جميع السماتlocal cabbage = script.Parentlocal cabbageAttributes = cabbage:GetAttributes()print(cabbageAttributes.GrowthRate) --> 2for k, v in cabbageAttributes doprint(k, v)end
حذف السمات
لحذف سمة، قم بضبط قيمتها على nil.
حذف سمةlocal cabbage = script.Parentcabbage:SetAttribute("GrowthRate", nil)
الكشف عن التغييرات
هناك عدة طرق للاستماع للتغييرات التي تحدث على الخصائص والسمات:
- يستمع حدث Instance.AttributeChanged للتغييرات على أي سمة ويمرر اسم السمة التي تغيرت كمعامل.
- تتيح لك طريقة Instance:GetPropertyChangedSignal() الاستماع للتغييرات على خاصية واحدة ولا تمرر أي معاملات.
- تتيح لك طريقة Instance:GetAttributeChangedSignal() الاستماع للتغييرات على سمة واحدة ولا تمرر أي معاملات.
نظرًا للمعلومات القليلة التي تمررها هذه الأحداث والطرق كمعاملات، فإن جميعها مناسبة للسلاسل المجهولة، وخاصة Instance:GetPropertyChangedSignal() و Instance:GetAttributeChangedSignal(). لمعرفة المزيد عن السلاسل المجهولة والعمل مع الأحداث، راجع الأحداث.
الاستماع للتغييرات
local cabbage = script.Parent
-- دوال محلية
local function onAnyPropertyChange(property)
-- تجاهل التغييرات على السمات
if property ~= "Attributes" then
print(property) --> Name
print(cabbage[property]) --> Cabbage1
end
end
local function onAnyAttributeChange(attribute)
print(attribute) --> Grow, GrowthRate
print(cabbage:GetAttribute(attribute)) --> false, 3
end
-- الاستماع للتغييرات والتواصل مع الدوال المحلية
cabbage.Changed:Connect(onAnyPropertyChange)
cabbage.AttributeChanged:Connect(onAnyAttributeChange)
-- الاستماع للتغييرات والتواصل مع سلاسل مجهولة
cabbage:GetPropertyChangedSignal("Name"):Connect(function()
print(cabbage.Name) --> Cabbage1
end)
cabbage:GetAttributeChangedSignal("GrowthRate"):Connect(function()
print(cabbage:GetAttribute("GrowthRate")) --> 3
end)
-- التشغيل بتغييرات Changed و GetPropertyChangedSignal()
cabbage.Name = "Cabbage1"
-- التشغيل بتغييرات Changed و AttributeChanged
cabbage:SetAttribute("Grow", false)
-- التشغيل بتغييرات Changed و AttributeChanged و GetAttributeChangedSignal()
cabbage:SetAttribute("GrowthRate", 3)