
為了應用你對模組腳本的知識,創建一個模組腳本,允許玩家撿起鑰匙並使用它們打開寶箱。
專案設置
此專案包括一個啟動地圖,帶有排行榜和用於鑰匙及寶箱的腳本化撿取物件。
載入啟動專案
在 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")-- 載入模組腳本 ⯆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")-- 載入模組腳本 ⯆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 的行。如果模組不包含 require,則無法使用該模組腳本中的函數和變數。
問題: 腳本不運行或無法撿起鑰匙。
在模組腳本中,確保所有代碼都在 local TreasureManager = {} 和 return TreasureManager 之間。返回必須是模組腳本中的最後一行代碼。
檢查在 require 行的末尾是否有兩個括號,例如 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 加到排行榜中的玩家鑰匙數量。

如果需要,檢查你的腳本與下面的腳本是否有任何故障排除問題。
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() 已經創建,可以在玩家觸碰寶箱時由寶箱部件調用,使用預製的 partTouched() 函數。
在 Workspace ⟩ Chests 中打開 ChestScript。
創建一個名為 treasureManager 的新變數,並在 ServerStorage 中要求 TreasureManager 模組腳本。
local ServerStorage = game:GetService("ServerStorage")-- 載入模組腳本 ⯆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 是否為 true。
如果是,調用 TreasureManager 的 openChest() 函數。
然後,傳遞兩個參數: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(),是否與課程中顯示的完全相同。任何差異都可能導致腳本中的微妙錯誤。
完成的腳本
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 TreasureManagerlocal ServerStorage = game:GetService("ServerStorage")
-- 載入模組腳本 ⯆
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")
-- 載入模組腳本 ⯆
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 的模組腳本,以處理在玩家與遊戲內物件互動時授予他們鑰匙和寶物。