أنشئ باستخدام سكريبتات الوحدات

*This content is translated using AI (Beta) and may contain errors. To view this page in English, click here.

لتطبيق معرفتك بسكريبتات الوحدات، أنشئ سكريبت وحدة يسمح للاعبين بالتقاط المفاتيح واستخدامها لفتح صناديق الكنز.

إعداد المشروع

يتضمن هذا المشروع خريطة بداية مع لوحة متصدرين وأشياء قابلة للاختيار مبرمجة للمفاتيح وصناديق الكنز.

تحميل مشروع البداية

  1. قم بتنزيل مشروع البداية.

  2. في Roblox Studio، افتح الملف الذي تم تنزيله: Intro to Module Scripts - Starter Project.rbxl.

إنشاء سكريبت وحدة

لكي يتمكن اللاعبون من الحصول على الكنز من الصناديق، أنشئ سكريبت وحدة باسم TreasureManager. سيوصل استخدام سكريبت الوحدة بين العناصر القابلة للاختيار ولوحات المتصدرين.

  1. في ServerStorage، أنشئ ModuleScript جديد وأعد تسميته إلى TreasureManager.

  2. في TreasureManager، أعد تسمية جدول الوحدة الافتراضي عن طريق استبدال module بـ TreasureManager في كلا المكانين.

    local TreasureManager = {}
    return TreasureManager

استخدام الدوال في سكريبتات الوحدة

لاختبار كيفية عمل الدوال في سكريبتات الوحدة، أنشئ دالة جديدة باسم getKey(). عند استدعاء دالة getKey() من سكريبت آخر، ستتلقى جزء المفتاح لتدميره وإضافة 1 إلى عدد المفاتيح في مخزون اللاعب.

إنشاء دالة وحدة للمفاتيح

  1. سيستخدم هذا السكريبت مجموعة من الدوال المحلية ودوال الوحدة، اكتب تعليقين لمساعدتك في فصلها.

    local TreasureManager = {}
    ------------------ Local Functions
    ------------------ Module Functions
    return TreasureManager
  2. تحت تعليق Module Functions، أضف دالة وحدة جديدة إلى TreasureManager باسم getKey().

    استخدم معاملين:

    • keyPart - الجزء الذي سيتم تدميره.
    • whichCharacter - اللاعب الذي لمس جزء المفتاح.
    local TreasureManager = {}
    ------------------ Local Functions
    ------------------ Module Functions
    function TreasureManager.getKey(keyPart, whichCharacter)
    end
    return TreasureManager
  3. في getKey(), دمر keyPart.

    function TreasureManager.getKey(keyPart, whichCharacter)
    keyPart:Destroy()
    end

استخدام دالة الوحدة

الآن، يمكن استخدام دالة الوحدة getKey() في سكريبتات أخرى. لاختبار تلك الدالة، ستفتح سكريبتًا مسبق الصنع وتستدعيه.

  1. افتح سكريبت المفتاح في WorkspaceKeysKeyScript.

  2. في 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.Parent
    local keysFolder = keys.Parts
    local keysArray = keysFolder:GetChildren()
  3. هناك بالفعل دالة باسم partTouched() للتحقق من لمس لاعب للجزء. داخل partTouched():

    • استدعِ دالة getKey() لوحدة لتدمير المفتاح.
    • مرر keyPart و whichCharacter.
    local 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
  4. قم بتشغيل المشروع وتحقق من أن لمس مفتاح يدمره.

نصائح استكشاف الأخطاء

المشكلة: الحصول على رسالة خطأ تتضمن: "Infinite yield possible".

  • تحقق من تهجئة سكريبت الوحدة في السكريبت. إذا كانت سكريبت الوحدة، مثل TreasureManager، مكتوبة بشكل مختلف، فسيكون هناك خطأ.

المشكلة: الحصول على رسالة خطأ تتضمن: "attempt to index global".

  • تحقق من السطر الذي يتضمن الاستدعاء للسكريبت في keyScript. إذا لم يتضمن السكريبت require، فلا يمكنه استخدام الدوال والمتغيرات من ذلك السكريبت.

المشكلة: السكريبت لا يعمل أو لا يمكنه التقاط المفاتيح.

  • في سكريبت الوحدة، تأكد من أن كل الكود موجود بين local TreasureManager = {} و return TreasureManager. يجب أن يكون الإرجاع هو السطر الأخير من الكود في سكريبت الوحدة.

  • تحقق من وجود قوسين في نهاية السطر مع require، كما في WaitForChild("TreasureManager")).

إنشاء دالة محلية

في الوقت الحالي، تحتفظ لوحة المتصدرين بعدد مفاتيح اللاعب وكنزه. لتغيير أرقام لوحة المتصدرين، استخدم دالة محلية في سكريبت الوحدة. يتم استخدام دالة محلية لأن تغيير قيم مفاتيح اللاعب أو كنزه سيكون مطلوبًا فقط في سكريبت TreasureManager، وليس في أي مكان آخر.

  1. في ServerStorage، افتح سكريبت TreasureManager.

  2. أنشئ متغيرات محلية للقيام بما يلي:

    • الحصول على خدمة اللاعبين حتى يتمكن السكريبت من العمل مع إحصائيات لوحة المتصدرين للاعبين.

    • تخزين عدد المفاتيح التي يحصل عليها اللاعب بعد لمس keyPart.

    local TreasureManager = {}
    local Players = game:GetService("Players")
    local keyDrop = 1
    ------------------ Local Functions
    ------------------ Module Functions
    function TreasureManager.getKey(keyPart, whichCharacter)
    keyPart:Destroy()
    end
    return TreasureManager
  3. انسخ والصق هاتين الدالتين المحليتين في قسم Local Functions.

    • getPlayerKeys() تعيد قيمة Lockpicks leaderstat للاعب.

    • getPlayerTreasure() تعيد قيمة Treasure leaderstat للاعب.

    ------------------ 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
  4. لإضافة مفاتيح اللاعب، في دالة getKey() لوحدة:

    • أنشئ متغيرًا محليًا لاستدعاء getPlayerKeys(whichCharacter).

    • أضف قيمة keyDrop إلى playerKeys.

    ------------------ Module Functions
    function TreasureManager.getKey(keyPart, whichCharacter)
    local playerKeys = getPlayerKeys(whichCharacter)
    playerKeys.Value = playerKeys.Value + keyDrop
    keyPart:Destroy()
    end
  5. قم بتشغيل المشروع. تحقق من أن لمس مفتاح يدمره ويضيف 1 إلى مفاتيح اللاعب في لوحة المتصدرين.

إذا لزم الأمر، تحقق من سكريبتك مقابل السكريبت أدناه لأي مشاكل في استكشاف الأخطاء.

Current TreasureManager Script
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 عندما يلمس اللاعبون صندوق الكنز للتحقق مما إذا كان لديهم على الأقل مفتاح واحد قبل فتحه ومنحهم الذهب.

تحقق مما إذا كانت الصناديق يمكن فتحها

  1. أولاً في سكريبت TreasureManager في ServerStorage، قم بإعداد متغيرات لعدد المفاتيح التي تكلف لفتح صندوق، وكمية الذهب التي يحتوي عليها كل صندوق.

    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
  2. لإنشاء دالة تتحقق مما إذا كان بإمكان اللاعب فتح صندوق، في قسم Module Functions، أضف دالة جديدة إلى جدول TreasureManager باسم canOpenChest() مع المعامل whichCharacter.

    ------------------ Module Functions
    function TreasureManager.canOpenChest(whichCharacter)
    end
    function TreasureManager.getKey(keyPart, whichCharacter)
    local playerKeys = getPlayerKeys(whichCharacter)
    playerKeys.Value = playerKeys.Value + keyDrop
    keyPart:Destroy()
    end
  3. انسخ والصق الكود أدناه في canOpenChest() لإرجاع true إذا كان لدى اللاعب مفاتيح كافية، وfalse إذا لم يكن لديهم.

    function TreasureManager.canOpenChest(whichCharacter)
    local playerKeys = getPlayerKeys(whichCharacter)
    if playerKeys.Value >= chestPickCost then
    return true
    else
    return false
    end
    end

منح اللاعبين الكنز

لكي يتمكن اللاعب من فتح صندوق، أنشئ دالة في TreasureManager تمنحهم الكنز.

  1. أضف دالة وحدة جديدة إلى TreasureManager باسم openChest().

    مرر في وسيطين:

    • chestPart - جزء الصندوق الذي سيتم تدميره.
    • whichCharacter - اللاعب الذي سيتم منح الكنز له.
    function TreasureManager.openChest(chestPart, whichCharacter)
    end
  2. لخصم مفاتيح اللاعب ومنحهم الكنز، انسخ والصق الكود أدناه في openChest(). يستخدم هذا الكود المتغيرات التي تم إنشاؤها سابقًا، مثل chestReward، مقدار الكنز الممنوح لكل صندوق.

    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

استدعاء دوال الصندوق

الآن بعد أن تم إنشاء دالتي الوحدة، canOpenChest() و openChest()، يمكن استدعاؤهما بواسطة أجزاء الصندوق كلما لمسها لاعب باستخدام دالة partTouched() المسبقة الصنع.

  1. في WorkspaceChests افتح ChestScript.

  2. أنشئ متغيرًا جديدًا باسم treasureManager واطلب سكريبت وحدة TreasureManager في ServerStorage.

    local 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()
  3. في partTouched(), تحت جملة if humanoid، أنشئ متغيرًا جديدًا باسم canOpen واضبطه على:

    treasureManager.canOpenChest(whichCharacter)

    local function partTouched(otherPart, chestPart)
    local whichCharacter = otherPart.Parent
    local humanoid = whichCharacter:FindFirstChildWhichIsA("Humanoid")
    if humanoid then
    -- تحقق مما إذا كان بإمكان اللاعب فتح صندوق، ثم دعهم يحصلون على الكنز
    -- =============================================
    local canOpen = treasureManager.canOpenChest(whichCharacter)
    -- =============================================
    end
    end
  4. بعد ذلك، أنشئ جملة if للتحقق مما إذا كان canOpen صحيحًا.

    • إذا كان الأمر كذلك، استدعِ دالة openChest() من TreasureManager.

    • ثم، مرر وسيطين: chestPart، الصندوق الذي سيتم تدميره، و whichCharacter، اللاعب الذي سيتم منح الكنز له.

    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
  5. قم بتشغيل المشروع. تحقق من أن:

    • إذا كان لديك على الأقل مفتاح واحد، فإن لمس صندوق يدمره ويمنح الكنز.
    • إذا كان لديك 0 مفاتيح، فلا يمكنك فتح صندوق الكنز.

نصائح استكشاف الأخطاء

  • في ChestScript، تأكد من أن الدوال المستدعاة من سكريبت الوحدة مثل canOpenChest() مكتوبة بالضبط كما هي موجودة في سكريبت TreasureManager. أي اختلاف سيسبب خطأ.

  • تحقق من أن الدوال المنسوخة والمقاسة، مثل treasureManager.openChest(), هي بالضبط كما هو موضح في الدرس. أي اختلافات يمكن أن تسبب أخطاء دقيقة في السكريبت.

السكريبتات المنتهية

Finished TreasureManager Script
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 TreasureManager
Finished ChestScript
local 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)
end
Finished keyScript
local 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 للتعامل مع منح اللاعبين المفاتيح والكنز كلما تفاعلوا مع العناصر داخل اللعبة.

©2026 شركة Roblox Corporation. تُعد منصّة Roblox، وشعار Roblox وشعار "توسيع حدود المخيلة"، من ضمن علاماتنا التجارية المسجّلة وغير المسجّلة في الولايات المتحدة وبلدان أخرى.