使用模块脚本创建

*此内容使用人工智能(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 中包含要求的模块脚本的行。如果模块不包含要求,无法使用该模块脚本中的函数和变量。

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

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

  • 确保在要求行末尾有两个括号,如 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 leaderboard 数值。

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


    ------------------ 本地函数
    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 把钥匙,触碰宝箱将会摧毁它并给予宝藏。
    • 如果你没有钥匙,则无法打开宝箱。

故障排除提示

  • 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 是我们在美国及其他国家或地区的注册与未注册商标。