
為了應用你對模組腳本的知識,創建一個模組腳本,讓玩家能夠拾起鑰匙並用它們來打開寶藏箱。
專案設置
此專案包含一個起始地圖,帶有排行榜和用於鑰匙及寶藏箱的腳本拾取物件。
加載起始專案
在 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執行專案並檢查觸摸到鑰匙是否將其銷毀。
疑難解決提示
問題: 獲得錯誤訊息,包括:“無限收益可能”。
- 檢查腳本中模組腳本的拼寫。如果模組腳本,如 TreasureManager,拼寫不正確,將會出現錯誤。
問題: 獲得錯誤訊息,包括:“嘗試索引全局”。
- 檢查 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 leaderboard 值。
getPlayerTreasure() 返回玩家的 Treasure leaderboard 值。
------------------ 本地函數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。

如有需要,對照下面的腳本檢查你的腳本是否存在任何疑難問題。
當前 TreasureManager 腳本
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 是否為真。
若為真,則調用 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(),與課程中顯示的絕對相同。任何差異都可能導致腳本中的微妙錯誤。
完成的腳本
完成的 TreasureManager 腳本
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
完成的 ChestScript
local 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)
end
完成的 keyScript
local 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 的模組腳本,用於在玩家與遊戲中的物件互動時授予他們鑰匙和寶藏。