使用模块脚本创建

*此内容使用人工智能(Beta)翻译,可能包含错误。若要查看英文页面,请点按 此处

为了应用你对模块脚本的知识,创建一个模块脚本,允许玩家拾取钥匙并使用它们打开宝箱。

项目设置

该项目包括一个带有排行榜和脚本化拾取物体的起始地图,用于钥匙和宝箱。

加载起始项目

  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 = {}
    ------------------ 本地函数
    ------------------ 模块函数
    return TreasureManager
  2. 模块函数 注释下,向 TreasureManager 添加一个名为 getKey() 的新模块函数。

    使用两个参数:

    • keyPart - 要销毁的部件。
    • whichCharacter - 触碰钥匙部件的玩家。
    local TreasureManager = {}
    ------------------ 本地函数
    ------------------ 模块函数
    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")
    -- 在下面要求模块脚本 ⯆
    local treasureManager = require(ServerStorage:WaitForChild("TreasureManager"))
    local keys = script.Parent
    local keysFolder = keys.Parts
    local keysArray = keysFolder:GetChildren()
  3. 已经有一个名为 partTouched() 的函数来检查玩家是否触碰了该部件。在 partTouched() 中:

    • 调用 getKey() 模块函数以销毁钥匙。
    • 传入 keyPartwhichCharacter
    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
  4. 运行项目并检查触碰钥匙是否会销毁它。

故障排除提示

问题: 收到错误消息,包括:“"Infinite yield possible"”。

  • 检查脚本中模块脚本的拼写。如果模块脚本,如 TreasureManager,拼写不同,将会出现错误。

问题: 收到错误消息,包括:“"attempt to index global"”。

  • 检查 keyScript 中包含模块脚本的 require 的行。如果模块不包含 require,它将无法使用该模块脚本中的函数和变量。

问题: 脚本未运行或无法拾取钥匙。

  • 在模块脚本中,确保所有代码都在 local TreasureManager = {}return TreasureManager 之间。返回必须是模块脚本中的最后一行代码。

  • 检查 require 行末尾是否有两个括号,如 WaitForChild("TreasureManager"))

创建本地函数

现在,排行榜跟踪玩家的钥匙和宝物。要更改排行榜数字,请在模块脚本中使用本地函数。使用本地函数是因为更改玩家的钥匙或宝物值只需要在 TreasureManager 脚本中,而不需要在其他地方。

  1. ServerStorage 中,打开 TreasureManager 脚本。

  2. 创建本地变量以执行以下操作:

    • 获取 Players 服务,以便脚本可以处理玩家的排行榜统计信息。

    • 存储玩家在触碰 keyPart 后获得的钥匙数量。

    local TreasureManager = {}
    local Players = game:GetService("Players")
    local keyDrop = 1
    ------------------ 本地函数
    ------------------ 模块函数
    function TreasureManager.getKey(keyPart, whichCharacter)
    keyPart:Destroy()
    end
    return TreasureManager
  3. 将这两个本地函数复制并粘贴到 本地函数 部分。

    • getPlayerKeys() 返回玩家的 Lockpicks leaderstat 的值。

    • getPlayerTreasure() 返回玩家的 Treasure leaderstat 的值。

    ------------------ 本地函数
    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
    ------------------ 模块函数
  4. 为了增加玩家的钥匙,在 getKey() 模块函数中:

    • 创建一个 local 变量来调用 getPlayerKeys(whichCharacter)

    • keyDrop 的值加到 playerKeys 中。

    ------------------ 模块函数
    function TreasureManager.getKey(keyPart, whichCharacter)
    local playerKeys = getPlayerKeys(whichCharacter)
    playerKeys.Value = playerKeys.Value + keyDrop
    keyPart:Destroy()
    end
  5. 运行项目。检查触碰钥匙是否会销毁它并在排行榜中增加 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 模块脚本将在玩家触碰宝箱时使用,以检查他们是否至少有一把钥匙,然后再打开宝箱并给予他们金币。

检查宝箱是否可以打开

  1. 首先在 ServerStorageTreasureManager 脚本中,设置打开宝箱所需的钥匙数量和每个宝箱包含的金币数量的变量。

    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
  2. 为了创建一个检查玩家是否可以打开宝箱的函数,在 模块函数 部分,向 TreasureManager 表添加一个名为 canOpenChest() 的新函数,参数为 whichCharacter

    ------------------ 模块函数
    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 的新变量,并在 ServerStorage 中要求 TreasureManager 模块脚本。

    local ServerStorage = game:GetService("ServerStorage")
    -- 在下面要求模块脚本
    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 是否为 true。

    • 如果是,调用 TreasureManager 的 openChest() 函数。

    • 然后,传入两个参数: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. 运行项目。检查:

    • 如果你至少有 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 的模块脚本,以处理在玩家与游戏内物体交互时给予他们钥匙和宝物。

©2026 Roblox Corporation、Roblox、Roblox 标志及 Powering Imagination 是我们在美国及其他国家或地区的注册与未注册商标。