
لتطبيق معرفتك بسكريبتات الوحدات، أنشئ سكريبت وحدة يسمح للاعبين بالتقاط المفاتيح واستخدامها لفتح صناديق الكنز.
إعداد المشروع
يتضمن هذا المشروع خريطة بداية مع لوحة متصدرين وأشياء قابلة للاختيار مبرمجة للمفاتيح وصناديق الكنز.
تحميل مشروع البداية
في Roblox Studio، افتح الملف الذي تم تنزيله: Intro to Module Scripts - Starter Project.rbxl.

إنشاء سكريبت وحدة
لكي يتمكن اللاعبون من الحصول على الكنز من الصناديق، أنشئ سكريبت وحدة باسم TreasureManager. سيوصل استخدام سكريبت الوحدة بين العناصر القابلة للاختيار ولوحات المتصدرين.
في ServerStorage، أنشئ ModuleScript جديد وأعد تسميته إلى TreasureManager.

في TreasureManager، أعد تسمية جدول الوحدة الافتراضي عن طريق استبدال module بـ TreasureManager في كلا المكانين.
local TreasureManager = {}return TreasureManager
استخدام الدوال في سكريبتات الوحدة
لاختبار كيفية عمل الدوال في سكريبتات الوحدة، أنشئ دالة جديدة باسم getKey(). عند استدعاء دالة getKey() من سكريبت آخر، ستتلقى جزء المفتاح لتدميره وإضافة 1 إلى عدد المفاتيح في مخزون اللاعب.
إنشاء دالة وحدة للمفاتيح
سيستخدم هذا السكريبت مجموعة من الدوال المحلية ودوال الوحدة، اكتب تعليقين لمساعدتك في فصلها.
local TreasureManager = {}------------------ Local Functions------------------ Module Functionsreturn TreasureManagerتحت تعليق Module Functions، أضف دالة وحدة جديدة إلى TreasureManager باسم getKey().
استخدم معاملين:
- keyPart - الجزء الذي سيتم تدميره.
- whichCharacter - اللاعب الذي لمس جزء المفتاح.
local TreasureManager = {}------------------ Local Functions------------------ Module Functionsfunction TreasureManager.getKey(keyPart, whichCharacter)endreturn TreasureManagerفي getKey(), دمر keyPart.
function TreasureManager.getKey(keyPart, whichCharacter)keyPart:Destroy()end
استخدام دالة الوحدة
الآن، يمكن استخدام دالة الوحدة getKey() في سكريبتات أخرى. لاختبار تلك الدالة، ستفتح سكريبتًا مسبق الصنع وتستدعيه.
افتح سكريبت المفتاح في Workspace ⟩ Keys ⟩ KeyScript.
في keyScript، قم بتخزين سكريبت الوحدة في متغير باسم treasureManager واضبطه على: require(ServerStorage:WaitForChild("TreasureManager"))
local ServerStorage = game:GetService("ServerStorage")-- Require the module script below ⯆local treasureManager = require(ServerStorage:WaitForChild("TreasureManager"))local keys = script.Parentlocal keysFolder = keys.Partslocal keysArray = keysFolder:GetChildren()هناك بالفعل دالة باسم partTouched() للتحقق من لمس لاعب للجزء. داخل partTouched():
- استدعِ دالة getKey() لوحدة لتدمير المفتاح.
- مرر keyPart و whichCharacter.
local ServerStorage = game:GetService("ServerStorage")-- Require the module script below ⯆local treasureManager = require(ServerStorage:WaitForChild("TreasureManager"))local keys = script.Parentlocal keysFolder = keys.Partslocal keysArray = keysFolder:GetChildren()local function partTouched(otherPart, keyPart)local whichCharacter = otherPart.Parentlocal humanoid = whichCharacter:FindFirstChildWhichIsA("Humanoid")if humanoid then-- أعط اللاعب مفتاحًا ودمّر جزء المفتاح-- =============================================treasureManager.getKey(keyPart, whichCharacter)-- =============================================endendقم بتشغيل المشروع وتحقق من أن لمس مفتاح يدمره.
نصائح استكشاف الأخطاء
المشكلة: الحصول على رسالة خطأ تتضمن: "Infinite yield possible".
- تحقق من تهجئة سكريبت الوحدة في السكريبت. إذا كانت سكريبت الوحدة، مثل TreasureManager، مكتوبة بشكل مختلف، فسيكون هناك خطأ.
المشكلة: الحصول على رسالة خطأ تتضمن: "attempt to index global".
- تحقق من السطر الذي يتضمن الاستدعاء للسكريبت في keyScript. إذا لم يتضمن السكريبت require، فلا يمكنه استخدام الدوال والمتغيرات من ذلك السكريبت.
المشكلة: السكريبت لا يعمل أو لا يمكنه التقاط المفاتيح.
في سكريبت الوحدة، تأكد من أن كل الكود موجود بين local TreasureManager = {} و return TreasureManager. يجب أن يكون الإرجاع هو السطر الأخير من الكود في سكريبت الوحدة.
تحقق من وجود قوسين في نهاية السطر مع require، كما في WaitForChild("TreasureManager")).
إنشاء دالة محلية
في الوقت الحالي، تحتفظ لوحة المتصدرين بعدد مفاتيح اللاعب وكنزه. لتغيير أرقام لوحة المتصدرين، استخدم دالة محلية في سكريبت الوحدة. يتم استخدام دالة محلية لأن تغيير قيم مفاتيح اللاعب أو كنزه سيكون مطلوبًا فقط في سكريبت TreasureManager، وليس في أي مكان آخر.
في ServerStorage، افتح سكريبت TreasureManager.
أنشئ متغيرات محلية للقيام بما يلي:
الحصول على خدمة اللاعبين حتى يتمكن السكريبت من العمل مع إحصائيات لوحة المتصدرين للاعبين.
تخزين عدد المفاتيح التي يحصل عليها اللاعب بعد لمس keyPart.
local TreasureManager = {}local Players = game:GetService("Players")local keyDrop = 1------------------ Local Functions------------------ Module Functionsfunction TreasureManager.getKey(keyPart, whichCharacter)keyPart:Destroy()endreturn TreasureManagerانسخ والصق هاتين الدالتين المحليتين في قسم Local Functions.
getPlayerKeys() تعيد قيمة Lockpicks leaderstat للاعب.
getPlayerTreasure() تعيد قيمة Treasure leaderstat للاعب.
------------------ Local Functionslocal function getPlayerKeys(whichCharacter)local player = Players:GetPlayerFromCharacter(whichCharacter)local leaderstats = player:FindFirstChild("leaderstats")return leaderstats:WaitForChild("Lockpicks")endlocal function getPlayerTreasure(whichCharacter)local player = Players:GetPlayerFromCharacter(whichCharacter)local leaderstats = player:FindFirstChild("leaderstats")return leaderstats:WaitForChild("Treasure")end------------------ Module Functionsلإضافة مفاتيح اللاعب، في دالة getKey() لوحدة:
أنشئ متغيرًا محليًا لاستدعاء getPlayerKeys(whichCharacter).
أضف قيمة keyDrop إلى playerKeys.
------------------ Module Functionsfunction TreasureManager.getKey(keyPart, whichCharacter)local playerKeys = getPlayerKeys(whichCharacter)playerKeys.Value = playerKeys.Value + keyDropkeyPart:Destroy()endقم بتشغيل المشروع. تحقق من أن لمس مفتاح يدمره ويضيف 1 إلى مفاتيح اللاعب في لوحة المتصدرين.

إذا لزم الأمر، تحقق من سكريبتك مقابل السكريبت أدناه لأي مشاكل في استكشاف الأخطاء.
local TreasureManager = {}
local Players = game:GetService("Players")
local keyDrop = 1
------------------ Local Functions
local function getPlayerKeys(whichCharacter)
local player = Players:GetPlayerFromCharacter(whichCharacter)
local leaderstats = player:FindFirstChild("leaderstats")
return leaderstats:WaitForChild("Lockpicks")
end
local function getPlayerTreasure(whichCharacter)
local player = Players:GetPlayerFromCharacter(whichCharacter)
local leaderstats = player:FindFirstChild("leaderstats")
return leaderstats:WaitForChild("Treasure")
end
------------------ Module Functions
function TreasureManager.getKey(keyPart, whichCharacter)
local playerKeys = getPlayerKeys(whichCharacter)
playerKeys.Value = playerKeys.Value + keyDrop
keyPart:Destroy()
end
return TreasureManagerالحصول على معلومات من سكريبتات الوحدة
سيتم استخدام سكريبت وحدة TreasureManager عندما يلمس اللاعبون صندوق الكنز للتحقق مما إذا كان لديهم على الأقل مفتاح واحد قبل فتحه ومنحهم الذهب.
تحقق مما إذا كانت الصناديق يمكن فتحها
أولاً في سكريبت TreasureManager في ServerStorage، قم بإعداد متغيرات لعدد المفاتيح التي تكلف لفتح صندوق، وكمية الذهب التي يحتوي عليها كل صندوق.
local TreasureManager = {}local Players = game:GetService("Players")local keyDrop = 1local chestPickCost = 1local chestReward = 100------------------ Local Functionslocal function getPlayerKeys(whichCharacter)local player = Players:GetPlayerFromCharacter(whichCharacter)local leaderstats = player:FindFirstChild("leaderstats")return leaderstats:WaitForChild("Lockpicks")endلإنشاء دالة تتحقق مما إذا كان بإمكان اللاعب فتح صندوق، في قسم Module Functions، أضف دالة جديدة إلى جدول TreasureManager باسم canOpenChest() مع المعامل whichCharacter.
------------------ Module Functionsfunction TreasureManager.canOpenChest(whichCharacter)endfunction TreasureManager.getKey(keyPart, whichCharacter)local playerKeys = getPlayerKeys(whichCharacter)playerKeys.Value = playerKeys.Value + keyDropkeyPart:Destroy()endانسخ والصق الكود أدناه في canOpenChest() لإرجاع true إذا كان لدى اللاعب مفاتيح كافية، وfalse إذا لم يكن لديهم.
function TreasureManager.canOpenChest(whichCharacter)local playerKeys = getPlayerKeys(whichCharacter)if playerKeys.Value >= chestPickCost thenreturn trueelsereturn falseendend
منح اللاعبين الكنز
لكي يتمكن اللاعب من فتح صندوق، أنشئ دالة في TreasureManager تمنحهم الكنز.
أضف دالة وحدة جديدة إلى TreasureManager باسم openChest().
مرر في وسيطين:
- chestPart - جزء الصندوق الذي سيتم تدميره.
- whichCharacter - اللاعب الذي سيتم منح الكنز له.
function TreasureManager.openChest(chestPart, whichCharacter)endلخصم مفاتيح اللاعب ومنحهم الكنز، انسخ والصق الكود أدناه في openChest(). يستخدم هذا الكود المتغيرات التي تم إنشاؤها سابقًا، مثل chestReward، مقدار الكنز الممنوح لكل صندوق.
function TreasureManager.openChest(chestPart, whichCharacter)local playerKeys = getPlayerKeys(whichCharacter)local playerTreasure = getPlayerTreasure(whichCharacter)playerKeys.Value = playerKeys.Value - chestPickCostplayerTreasure.Value = playerTreasure.Value + chestRewardchestPart.Parent:Destroy()end
استدعاء دوال الصندوق
الآن بعد أن تم إنشاء دالتي الوحدة، canOpenChest() و openChest()، يمكن استدعاؤهما بواسطة أجزاء الصندوق كلما لمسها لاعب باستخدام دالة partTouched() المسبقة الصنع.
في Workspace ⟩ Chests افتح ChestScript.
أنشئ متغيرًا جديدًا باسم treasureManager واطلب سكريبت وحدة TreasureManager في ServerStorage.
local ServerStorage = game:GetService("ServerStorage")-- Require the module script belowlocal treasureManager = require(ServerStorage:WaitForChild("TreasureManager"))local chests = script.Parentlocal chestsFolder = chests.Partslocal chestsArray = chestsFolder:GetChildren()في partTouched(), تحت جملة if humanoid، أنشئ متغيرًا جديدًا باسم canOpen واضبطه على:
treasureManager.canOpenChest(whichCharacter)
local function partTouched(otherPart, chestPart)local whichCharacter = otherPart.Parentlocal humanoid = whichCharacter:FindFirstChildWhichIsA("Humanoid")if humanoid then-- تحقق مما إذا كان بإمكان اللاعب فتح صندوق، ثم دعهم يحصلون على الكنز-- =============================================local canOpen = treasureManager.canOpenChest(whichCharacter)-- =============================================endendبعد ذلك، أنشئ جملة if للتحقق مما إذا كان canOpen صحيحًا.
إذا كان الأمر كذلك، استدعِ دالة openChest() من TreasureManager.
ثم، مرر وسيطين: chestPart، الصندوق الذي سيتم تدميره، و whichCharacter، اللاعب الذي سيتم منح الكنز له.
local function partTouched(otherPart, chestPart)local whichCharacter = otherPart.Parentlocal humanoid = whichCharacter:FindFirstChildWhichIsA("Humanoid")if humanoid then-- تحقق مما إذا كان بإمكان اللاعب فتح صندوق، ثم دعهم يحصلون على الكنز-- =============================================local canOpen = treasureManager.canOpenChest(whichCharacter)if canOpen == true thentreasureManager.openChest(chestPart, whichCharacter)end-- =============================================endendقم بتشغيل المشروع. تحقق من أن:
- إذا كان لديك على الأقل مفتاح واحد، فإن لمس صندوق يدمره ويمنح الكنز.
- إذا كان لديك 0 مفاتيح، فلا يمكنك فتح صندوق الكنز.
نصائح استكشاف الأخطاء
في ChestScript، تأكد من أن الدوال المستدعاة من سكريبت الوحدة مثل canOpenChest() مكتوبة بالضبط كما هي موجودة في سكريبت TreasureManager. أي اختلاف سيسبب خطأ.
تحقق من أن الدوال المنسوخة والمقاسة، مثل treasureManager.openChest(), هي بالضبط كما هو موضح في الدرس. أي اختلافات يمكن أن تسبب أخطاء دقيقة في السكريبت.
السكريبتات المنتهية
local TreasureManager = {}
local Players = game:GetService("Players")
local keyDrop = 1
local chestPickCost = 1
local chestReward = 100
------------------ Local Functions
local function getPlayerKeys(whichCharacter)
local player = Players:GetPlayerFromCharacter(whichCharacter)
local leaderstats = player:FindFirstChild("leaderstats")
return leaderstats:WaitForChild("Lockpicks")
end
local function getPlayerTreasure(whichCharacter)
local player = Players:GetPlayerFromCharacter(whichCharacter)
local leaderstats = player:FindFirstChild("leaderstats")
return leaderstats:WaitForChild("Treasure")
end
------------------ Module Functions
function TreasureManager.openChest(chestPart, whichCharacter)
local playerKeys = getPlayerKeys(whichCharacter)
local playerTreasure = getPlayerTreasure(whichCharacter)
playerKeys.Value = playerKeys.Value - chestPickCost
playerTreasure.Value = playerTreasure.Value + chestReward
chestPart.Parent:Destroy()
end
function TreasureManager.canOpenChest(whichCharacter)
local playerKeys = getPlayerKeys(whichCharacter)
if playerKeys.Value >= chestPickCost then
return true
else
return false
end
end
function TreasureManager.getKey(keyPart, whichCharacter)
local playerKeys = getPlayerKeys(whichCharacter)
playerKeys.Value = playerKeys.Value + keyDrop
keyPart:Destroy()
end
return TreasureManagerlocal ServerStorage = game:GetService("ServerStorage")
-- Require the module script below ⯆
local treasureManager = require(ServerStorage:WaitForChild("TreasureManager"))
local chests = script.Parent
local chestsFolder = chests.Parts
local chestsArray = chestsFolder:GetChildren()
local function partTouched(otherPart, chestPart)
local whichCharacter = otherPart.Parent
local humanoid = whichCharacter:FindFirstChildWhichIsA("Humanoid")
if humanoid then
-- تحقق مما إذا كان بإمكان اللاعب فتح صندوق، ثم دعهم يحصلون على الكنز
-- =============================================
local canOpen = treasureManager.canOpenChest(whichCharacter)
if canOpen == true then
treasureManager.openChest(chestPart, whichCharacter)
end
-- =============================================
end
end
-- يربط كل جزء من الصندوق بدالة اللمس بحيث تعمل على جميع الأجزاء
for chestIndex = 1, #chestsArray do
local chestPart = chestsArray[chestIndex]:WaitForChild("Collider")
chestPart.Touched:Connect(function(otherPart)
partTouched(otherPart, chestPart)
end)
endlocal ServerStorage = game:GetService("ServerStorage")
-- Require the module script below ⯆
local treasureManager = require(ServerStorage:WaitForChild("TreasureManager"))
local keys = script.Parent
local keysFolder = keys.Parts
local keysArray = keysFolder:GetChildren()
local function partTouched(otherPart, keyPart)
local whichCharacter = otherPart.Parent
local humanoid = whichCharacter:FindFirstChildWhichIsA("Humanoid")
if humanoid then
-- أعط اللاعب مفتاحًا ودمّر جزء المفتاح
-- =============================================
treasureManager.getKey(keyPart, whichCharacter)
-- =============================================
end
end
-- يربط كل جزء من المفتاح بدالة اللمس بحيث تعمل على جميع الأجزاء
for keyIndex = 1, #keysArray do
local keyPart = keysArray[keyIndex]
keyPart.Touched:Connect(function(otherPart)
partTouched(otherPart, keyPart)
end)
endملخص
تطبيق شائع لاستخدام سكريبتات الوحدة في ألعاب Roblox هو التعامل مع المهام الشائعة التي يستخدمها اللاعبون، مثل منحهم النقاط. في هذا المثال، تم إنشاء سكريبت وحدة باسم TreasureManager للتعامل مع منح اللاعبين المفاتيح والكنز كلما تفاعلوا مع العناصر داخل اللعبة.