
เพื่อใช้ความรู้ของคุณเกี่ยวกับสคริปต์โมดูล ให้สร้างสคริปต์โมดูลที่ช่วยให้ผู้เล่นเก็บกุญแจและใช้ภูเขาเพื่อเปิดหีบสมบัติ
การตั้งค่าโครงการ
โครงการนี้ประกอบด้วยแผนที่เริ่มต้นพร้อมกับลีดเดอร์บอร์ดและวัตถุการเก็บข้อมูลที่ถูกสคริปต์สำหรับกุญแจและหีบสมบัติ
โหลดโครงการเริ่มต้น
ใน 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 = {}------------------ ฟังก์ชันภายใน------------------ ฟังก์ชันโมดูลreturn TreasureManagerใต้คอมเมนต์ ฟังก์ชันโมดูล ให้เพิ่มฟังก์ชันโมดูลใหม่ลงใน TreasureManager ชื่อว่า getKey().
ใช้พารามิเตอร์สองอย่าง:
- keyPart - ชิ้นส่วนที่จะทำลาย
- whichCharacter - ผู้เล่นที่สัมผัสกับชิ้นส่วนกุญแจ
local TreasureManager = {}------------------ ฟังก์ชันภายใน------------------ ฟังก์ชันโมดูลfunction 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 สคริปต์โมดูลด้านล่าง ⯆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 สคริปต์โมดูลด้านล่าง ⯆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 หากโมดูลไม่มีการเรียกใช้งาน จะไม่สามารถใช้ฟังก์ชันและตัวแปรจากสคริปต์โมดูลนั้นได้
ปัญหา: สคริปต์ไม่ทำงานหรือไม่สามารถเก็บกุญแจได้
ในสคริปต์โมดูล ให้แน่ใจว่าทุกโค้ดอยู่ระหว่าง local TreasureManager = {} และ return TreasureManager การส่งค่าคืนจะต้องอยู่ในบรรทัดสุดท้ายของสคริปต์โมดูล
ตรวจสอบว่าเป็นวงเล็บสองอันที่ด้านปลายบรรทัดที่มีการเรียกใช้งาน เช่น WaitForChild("TreasureManager")).
สร้างฟังก์ชันภายใน
ในตอนนี้ ลีดเดอร์บอร์ดจะติดตามกุญแจและสมบัติของผู้เล่น เพื่อเปลี่ยนแปลงตัวเลขลีดเดอร์บอร์ด ให้ใช้ฟังก์ชันภายในในสคริปต์โมดูล ฟังก์ชันภายในถูกใช้เพราะการเปลี่ยนแปลงค่ากุญแจหรือสมบัติของผู้เล่นจะต้องใช้ในสคริปต์ TreasureManager เท่านั้น ไม่ต้องใช้ที่อื่น
ใน ServerStorage ให้เปิดสคริปต์ TreasureManager.
สร้างตัวแปรภายในเพื่อกระทำดังนี้:
รับบริการ Players เพื่อให้สคริปต์สามารถทำงานกับสถิติลีดเดอร์บอร์ดของผู้เล่น
เก็บจำนวนกุญแจที่ผู้เล่นจะได้รับหลังจากสัมผัส keyPart.
local TreasureManager = {}local Players = game:GetService("Players")local keyDrop = 1------------------ ฟังก์ชันภายใน------------------ ฟังก์ชันโมดูลfunction TreasureManager.getKey(keyPart, whichCharacter)keyPart:Destroy()endreturn TreasureManagerคัดลอกและวางฟังก์ชันภายในสองฟังก์ชันเหล่านี้เข้าไปในส่วน ฟังก์ชันภายใน.
getPlayerKeys() ส่งค่าของ Lockpicks leaderstat ของผู้เล่น
getPlayerTreasure() ส่งค่าของ Treasure leaderstat ของผู้เล่น
------------------ ฟังก์ชันภายในlocal 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------------------ ฟังก์ชันโมดูลเพื่อเพิ่มให้กับกุญแจของผู้เล่น ในฟังก์ชัน getKey() โมดูล:
สร้างตัวแปร local เพื่อติดต่อ getPlayerKeys(whichCharacter).
เพิ่มค่าของ keyDrop ลงใน playerKeys.
------------------ ฟังก์ชันโมดูลfunction TreasureManager.getKey(keyPart, whichCharacter)local playerKeys = getPlayerKeys(whichCharacter)playerKeys.Value = playerKeys.Value + keyDropkeyPart:Destroy()endรันโปรเจกต์ ตรวจสอบว่าการสัมผัสกุญแจจะทำลายมันและเพิ่ม 1 ลงในกุญแจของผู้เล่นในลีดเดอร์บอร์ด

หากจำเป็น สามารถตรวจสอบสคริปต์ของคุณกับสคริปต์ด้านล่างเพื่อตรวจสอบปัญหาต่าง ๆ
Current TreasureManager Script
local TreasureManager = {}
local Players = game:GetService("Players")
local keyDrop = 1
------------------ ฟังก์ชันภายใน
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
------------------ ฟังก์ชันโมดูล
function TreasureManager.getKey(keyPart, whichCharacter)
local playerKeys = getPlayerKeys(whichCharacter)
playerKeys.Value = playerKeys.Value + keyDrop
keyPart:Destroy()
end
return TreasureManager
รับข้อมูลจากสคริปต์โมดูล
สคริปต์โมดูล TreasureManager จะใช้เมื่อผู้เล่นสัมผัสหีบสมบัติเพื่อตรวจสอบว่าพวกเขามีกุญแจอย่างน้อยหนึ่งดอกก่อนที่จะเปิดมันและมอบทองให้
ตรวจสอบว่าหีบสามารถเปิดได้
ก่อนอื่นใน ServerStorage ⟩ สคริปต์ TreasureManager กำหนดค่าตัวแปรว่ามีกุญแจเท่าไหร่ที่ใช้เปิดหีบ และทองที่每หีบมีเท่าไหร่
local TreasureManager = {}local Players = game:GetService("Players")local keyDrop = 1local chestPickCost = 1local chestReward = 100------------------ ฟังก์ชันภายในlocal function getPlayerKeys(whichCharacter)local player = Players:GetPlayerFromCharacter(whichCharacter)local leaderstats = player:FindFirstChild("leaderstats")return leaderstats:WaitForChild("Lockpicks")endเพื่อสร้างฟังก์ชันที่ตรวจสอบว่าผู้เล่นสามารถเปิดหีบได้หรือไม่ ในส่วน ฟังก์ชันโมดูล ให้เพิ่มฟังก์ชันใหม่ลงในตาราง TreasureManager ชื่อว่า canOpenChest() พร้อมพารามิเตอร์ whichCharacter.
------------------ ฟังก์ชันโมดูลfunction 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() ได้ถูกสร้างขึ้นแล้ว ฟังก์ชันเหล่านี้สามารถถูกเรียกโดยชิ้นส่วน Chest ทุกครั้งที่ผู้เล่นสัมผัสพวกเขาผ่านฟังก์ชัน partTouched() ที่สร้างไว้ล่วงหน้า
ใน Workspace ⟩ Chests เปิด ChestScript.
สร้างตัวแปรใหม่ชื่อ treasureManager และเรียกใช้สคริปต์โมดูล TreasureManager ใน ServerStorage.
local ServerStorage = game:GetService("ServerStorage")-- Require สคริปต์โมดูลด้านล่างlocal 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รันโปรเจกต์ ตรวจสอบว่า:
- หากคุณมีอย่างน้อย 1 กุญแจ การสัมผัสหีบจะทำลายมันและมอบสมบัติ
- หากคุณมี 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 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
------------------ ฟังก์ชันโมดูล
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 สคริปต์โมดูลด้านล่าง ⯆
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 สคริปต์โมดูลด้านล่าง ⯆
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 ถูกสร้างขึ้นเพื่อจัดการการมอบกุญแจและสมบัติให้กับผู้เล่นเมื่อพวกเขาสัมผัสวัตถุในเกม