
Để áp dụng kiến thức của bạn về kịch bản mô-đun, hãy tạo một kịch bản mô-đun cho phép người chơi lấy chìa khóa và sử dụng chúng để mở rương kho báu.
Thiết lập dự án
Dự án này bao gồm một bản đồ khởi đầu với bảng điểm và các đối tượng lấy kịch bản cho chìa khóa và rương kho báu.
Tải dự án khởi đầu
Trong Roblox Studio, mở tệp đã tải về: Intro to Module Scripts - Starter Project.rbxl.

Tạo một kịch bản mô-đun
Để người chơi có thể lấy kho báu từ rương, hãy tạo một kịch bản mô-đun có tên là TreasureManager. Việc sử dụng kịch bản mô-đun sẽ kết nối các đối tượng lấy và bảng điểm lại với nhau.
Trong ServerStorage, tạo một ModuleScript mới và đổi tên thành TreasureManager.

Trong TreasureManager, đổi tên bảng mô-đun mặc định bằng cách thay thế module bằng TreasureManager ở cả hai nơi.
local TreasureManager = {}return TreasureManager
Sử dụng hàm trong kịch bản mô-đun
Để kiểm tra cách hoạt động của hàm trong kịch bản mô-đun, tạo một hàm mới có tên getKey(). Khi hàm getKey() được gọi từ một kịch bản khác, nó sẽ nhận một phần chìa khóa để hủy và cộng 1 vào số lượng chìa khóa trong kho của người chơi.
Tạo hàm mô-đun cho chìa khóa
Kịch bản mô-đun này sẽ sử dụng một sự kết hợp giữa hàm mô-đun và hàm cục bộ, hãy ghi hai chú thích để giúp bạn giữ chúng tách biệt.
local TreasureManager = {}------------------ Local Functions------------------ Module Functionsreturn TreasureManagerDưới chú thích Module Functions, thêm một hàm mô-đun mới cho TreasureManager có tên là getKey().
Sử dụng hai tham số:
- keyPart - phần cần hủy.
- whichCharacter - người chơi đã chạm vào phần chìa khóa.
local TreasureManager = {}------------------ Local Functions------------------ Module Functionsfunction TreasureManager.getKey(keyPart, whichCharacter)endreturn TreasureManagerTrong getKey(), hủy keyPart.
function TreasureManager.getKey(keyPart, whichCharacter)keyPart:Destroy()end
Sử dụng hàm mô-đun
Giờ đây, hàm mô-đun getKey() có thể được sử dụng trong các kịch bản khác. Để kiểm tra hàm đó, bạn sẽ mở một kịch bản đã được chuẩn bị sẵn và gọi nó.
Mở kịch bản chìa khóa trong Workspace ⟩ Keys ⟩ KeyScript.
Trong keyScript, lưu kịch bản mô-đun vào một biến có tên là treasureManager và đặt nó bằng: 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()Đã có một hàm có tên là partTouched() để kiểm tra người chơi chạm vào phần. Bên trong partTouched():
- Gọi hàm mô-đun getKey() để hủy chìa khóa.
- Truyền vào keyPart và 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-- Cung cấp cho người chơi một chìa khóa và hủy phần chìa khóa-- =============================================treasureManager.getKey(keyPart, whichCharacter)-- =============================================endendChạy dự án và kiểm tra rằng việc chạm vào một chìa khóa sẽ hủy nó.
Mẹo khắc phục sự cố
Vấn đề: Nhận thông báo lỗi bao gồm: "Infinite yield possible".
- Kiểm tra chính tả của kịch bản mô-đun của bạn trong một kịch bản. Nếu một kịch bản mô-đun như TreasureManager được viết khác đi, sẽ có một lỗi.
Vấn đề: Nhận thông báo lỗi bao gồm: "attempt to index global".
- Kiểm tra dòng mà bao gồm yêu cầu cho kịch bản mô-đun trong keyScript. Nếu mô-đun không bao gồm yêu cầu, nó không thể sử dụng các hàm và biến từ kịch bản mô-đun đó.
Vấn đề: Kịch bản không chạy hoặc không thể lấy chìa khóa.
Trong kịch bản mô-đun, hãy chắc chắn rằng tất cả các mã đều nằm giữa local TreasureManager = {} và return TreasureManager. Dòng trả về phải là dòng mã cuối cùng trong một Kịch bản Mô-đun.
Kiểm tra rằng có hai dấu ngoặc đơn ở cuối dòng có yêu cầu, như trong WaitForChild("TreasureManager")).
Tạo một Hàm Cục Bộ
Hiện tại, một bảng điểm theo dõi chìa khóa và kho báu của người chơi. Để thay đổi số liệu của bảng điểm, hãy sử dụng một hàm cục bộ trong kịch bản mô-đun. Một hàm cục bộ được sử dụng vì việc thay đổi giá trị chìa khóa hoặc kho báu của người chơi chỉ cần thiết trong kịch bản TreasureManager, không cần thiết ở nơi khác.
Trong ServerStorage, mở kịch bản TreasureManager.
Tạo các biến cục bộ để thực hiện các vấn đề sau:
Lấy dịch vụ Players để kịch bản có thể làm việc với số liệu bảng điểm của người chơi.
Lưu trữ số lượng chìa khóa mà người chơi nhận được sau khi chạm vào keyPart.
local TreasureManager = {}local Players = game:GetService("Players")local keyDrop = 1------------------ Local Functions------------------ Module Functionsfunction TreasureManager.getKey(keyPart, whichCharacter)keyPart:Destroy()endreturn TreasureManagerSao chép và dán hai hàm cục bộ này vào phần Local Functions.
getPlayerKeys() trả giá trị của Lockpicks leaderstat của người chơi.
getPlayerTreasure() trả giá trị của Treasure leaderstat của người chơi.
------------------ 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Để cộng thêm vào chìa khóa của người chơi, trong hàm mô-đun getKey():
Tạo một biến cục bộ để gọi getPlayerKeys(whichCharacter).
Cộng giá trị của keyDrop vào playerKeys.
------------------ Module Functionsfunction TreasureManager.getKey(keyPart, whichCharacter)local playerKeys = getPlayerKeys(whichCharacter)playerKeys.Value = playerKeys.Value + keyDropkeyPart:Destroy()endChạy dự án. Kiểm tra rằng việc chạm vào một chìa khóa sẽ hủy nó và cộng 1 vào số lượng chìa khóa của người chơi trong bảng điểm.

Nếu cần, hãy so sánh kịch bản của bạn với kịch bản dưới đây để phát hiện bất kỳ vấn đề nào.
Kịch bản TreasureManager Hiện tại
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
Lấy thông tin từ các kịch bản mô-đun
Kịch bản mô-đun TreasureManager sẽ được sử dụng khi người chơi chạm vào một rương kho báu để kiểm tra xem họ có ít nhất một chìa khóa trước khi mở và tặng cho họ vàng hay không.
Kiểm tra xem rương có thể được mở không
Đầu tiên trong kịch bản TreasureManager ⟩ ServerStorage, thiết lập các biến cho số lượng chìa khóa cần thiết để mở rương và số vàng mà mỗi rương chứa.
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Để tạo một hàm kiểm tra xem người chơi có thể mở rương hay không, trong phần Module Functions, thêm một hàm mới vào bảng TreasureManager có tên là canOpenChest() với tham số whichCharacter.
------------------ Module Functionsfunction TreasureManager.canOpenChest(whichCharacter)endfunction TreasureManager.getKey(keyPart, whichCharacter)local playerKeys = getPlayerKeys(whichCharacter)playerKeys.Value = playerKeys.Value + keyDropkeyPart:Destroy()endSao chép và dán mã dưới đây vào canOpenChest() để trả về true nếu người chơi có đủ chìa khóa, và false nếu họ không có.
function TreasureManager.canOpenChest(whichCharacter)local playerKeys = getPlayerKeys(whichCharacter)if playerKeys.Value >= chestPickCost thenreturn trueelsereturn falseendend
Tặng kho báu cho người chơi
Để người chơi có thể mở một rương, hãy tạo một hàm trong TreasureManager để thưởng cho họ kho báu.
Thêm một hàm mô-đun mới vào TreasureManager có tên là openChest().
Truyền vào hai đối số:
- chestPart - phần rương cần hủy.
- whichCharacter - người chơi để tặng kho báu.
function TreasureManager.openChest(chestPart, whichCharacter)endĐể trừ đi chìa khóa của người chơi và tặng họ kho báu, sao chép và dán mã dưới đây vào openChest(). Mã này sử dụng các biến đã được tạo trước đó, như chestReward, số vàng tặng cho mỗi rương.
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
Gọi các hàm rương
Bây giờ hai hàm mô-đun, canOpenChest() và openChest(), đã được tạo, chúng có thể được gọi bởi các phần Rương bất cứ khi nào một người chơi chạm vào chúng bằng cách sử dụng hàm partTouched() đã được chuẩn bị sẵn.
Trong Workspace ⟩ Chests mở ChestScript.
Tạo một biến mới có tên là treasureManager và yêu cầu kịch bản mô-đun TreasureManager trong 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()Trong partTouched(), dưới câu lệnh if humanoid, tạo một biến mới có tên là canOpen và đặt nó bằng:
treasureManager.canOpenChest(whichCharacter)
local function partTouched(otherPart, chestPart)local whichCharacter = otherPart.Parentlocal humanoid = whichCharacter:FindFirstChildWhichIsA("Humanoid")if humanoid then-- Kiểm tra xem người chơi có thể mở rương, sau đó để họ nhận kho báu-- =============================================local canOpen = treasureManager.canOpenChest(whichCharacter)-- =============================================endendTiếp theo, tạo một câu lệnh if để kiểm tra xem canOpen có đúng không.
Nếu đúng, gọi hàm openChest() của TreasureManager.
Sau đó, truyền vào hai tham số: chestPart, rương cần hủy, và whichCharacter, người chơi để tặng kho báu.
local function partTouched(otherPart, chestPart)local whichCharacter = otherPart.Parentlocal humanoid = whichCharacter:FindFirstChildWhichIsA("Humanoid")if humanoid then-- Kiểm tra xem người chơi có thể mở rương, sau đó để họ nhận kho báu-- =============================================local canOpen = treasureManager.canOpenChest(whichCharacter)if canOpen == true thentreasureManager.openChest(chestPart, whichCharacter)end-- =============================================endendChạy dự án. Kiểm tra rằng:
- Nếu bạn có ít nhất 1 chìa khóa, việc chạm vào một rương sẽ hủy nó và tặng kho báu.
- Nếu bạn có 0 chìa khóa, bạn không thể mở rương kho báu.
Mẹo khắc phục sự cố
Trong ChestScript, hãy đảm bảo rằng các hàm được gọi từ kịch bản mô-đun như canOpenChest() được viết chính xác như chúng tồn tại trong kịch bản TreasureManager. Bất kỳ sự khác biệt nào sẽ gây ra lỗi.
Kiểm tra rằng các hàm đã sao chép và dán, như treasureManager.openChest(), là chính xác như đã hiển thị trong bài học. Bất kỳ khác biệt nào cũng có thể gây ra các lỗi tinh vi trong kịch bản.
Kịch bản hoàn chỉnh
Kịch bản TreasureManager Hoàn chỉnh
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
Kịch bản ChestScript Hoàn chỉnh
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
-- Kiểm tra xem người chơi có thể mở một rương, sau đó để họ nhận kho báu
-- =============================================
local canOpen = treasureManager.canOpenChest(whichCharacter)
if canOpen == true then
treasureManager.openChest(chestPart, whichCharacter)
end
-- =============================================
end
end
-- Liên kết mọi phần rương với chức năng chạm để nó hoạt động trên tất cả các phần
for chestIndex = 1, #chestsArray do
local chestPart = chestsArray[chestIndex]:WaitForChild("Collider")
chestPart.Touched:Connect(function(otherPart)
partTouched(otherPart, chestPart)
end)
end
Kịch bản keyScript Hoàn chỉnh
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
-- Cung cấp cho người chơi một chìa khóa và hủy phần chìa khóa
-- =============================================
treasureManager.getKey(keyPart, whichCharacter)
-- =============================================
end
end
-- Liên kết mọi phần chìa khóa với chức năng chạm để nó hoạt động trên tất cả các phần
for keyIndex = 1, #keysArray do
local keyPart = keysArray[keyIndex]
keyPart.Touched:Connect(function(otherPart)
partTouched(otherPart, keyPart)
end)
end
Tóm tắt
Một ứng dụng phổ biến của việc sử dụng kịch bản mô-đun trong trải nghiệm Roblox là để xử lý các tác vụ chung mà người chơi sử dụng, chẳng hạn như cấp cho họ điểm. Trong ví dụ này, một kịch bản mô-đun có tên TreasureManager đã được tạo để xử lý việc tặng chìa khóa và kho báu cho người chơi mỗi khi họ tương tác với các đối tượng trong trò chơi.