随着项目变得复杂,思考脚本的组织方式变得重要。良好的组织实践可以确保代码不会在脚本之间重复,或变得难以管理。
一种更好的组织和重用代码的方法是使用 模块脚本,这是一种独特的脚本类型,存储了一组旨在满足共享目的的函数和变量,例如管理玩家的金钱或敌人。模块脚本中的代码可以被其他脚本使用。这样,当玩家完成任务或找到道具时,您可以从多个不同的脚本调用相同的给金币的函数。
通过将常用代码存储在模块脚本中,可以更轻松地维护和组织代码,因为只需对一个模块脚本进行更改,而不是更新多个脚本。
模块脚本基础
模块脚本实际上是与脚本对象不同的独立对象。在 Roblox 中,模块脚本可以用 紫色 图标表示。
创建模块脚本
当服务器端脚本使用时,模块脚本通常放置在 ServerScriptService 中,而当客户端本地脚本(例如 GUI 交互)使用时,则放置在 ReplicatedStorage 中。
- 在 ServerScriptService 中创建一个 ModuleScript。

模块脚本的结构
创建时,每个模块脚本都以以下代码开始:
local Module = {}
return Module这一行 local Module = {} 创建了一个表,或代码容器,用于存储模块的共享函数和变量。这个表应该重命名为模块的目的,例如 RewardManager 或 ParticleController。与其他变量(如 myVariable)使用驼峰命名法不同,建议模块表使用帕斯卡命名法并以大写字母开头(MyModule)。
local RewardManager = {}
return RewardManager为了让其他脚本可以使用模块的非本地函数或变量,每个模块都以 return MyModule 结束。每当另一个脚本尝试从模块获取代码时,return 允许该脚本访问存储在模块表中的代码。
向模块脚本添加内容
要向模块中添加可以在另一个脚本中使用的函数或变量,输入模块表的名称,后跟一个点和函数或变量的名称,例如 TestModule.myVariable。使用点运算符是将代码添加到表中的另一种方式,允许其他脚本在返回模块表时访问该代码。
local TestModule = {}
-- 向 'TestModule' 表添加一个变量
TestModule.myVariable = 100
-- 向 'TestModule' 表添加一个函数
function TestModule.doTask(player)
-- 占位符代码
end
return TestModule模块脚本中的作用域
要在外部脚本中使用模块函数或变量,不要 输入 local。
在变量和函数前输入 local 意味着它们 仅 可由该脚本使用。虽然这是减少错误和故障排除的良好实践,但您不能使模块脚本的函数和变量为本地。
任何仅由该模块脚本使用的代码仍应包含 local。例如,下面的代码包含本地变量 difficultyModifier,它只能在该模块脚本中使用,以及可以在模块外部脚本中使用的函数 getCoinReward()。
local RewardManager = {}
-- 仅在模块脚本中可用
local rewardCoins = 50
-- 仅在模块脚本中可用
local difficultyModifier = {
easy = 0.5,
normal = 1,
hard = 2
}
-- 在其他脚本中可用
function RewardManager.getCoinReward(difficulty)
local coins = difficultyModifier[difficulty] * rewardCoins
return coins
end
return RewardManager在其他脚本中使用模块
模块脚本本身无法运行代码 — 它需要在另一个脚本中使用关键字 require() 加载。函数 require() 接受一个参数,即模块脚本在资源管理器中的位置。
要使用模块,在单独的脚本中,将一个变量设置为 require(moduleScript)。
local MyModule = require(ServerStorage.ModuleScript)现在,变量 MyModule 包含在该模块脚本中创建的模块表。要使用该表中的函数和变量,输入变量名称,后跟一个点,以及在该模块脚本中要使用的确切名称,例如 MyModule.myFunction()。当脚本运行并到达该行时,它将访问存储在模块表中的特定函数或变量。
local MyModule = require(ServerStorage.ModuleScript)
MyModule.myFunction()RewardManager 示例
local RewardManager = {}
-- 仅在模块脚本中可用
local rewardCoins = 50
-- 仅在模块脚本中可用
local difficultyModifier = {
easy = 0.5,
normal = 1,
hard = 2
}
-- 在其他脚本中可用
function RewardManager.getCoinReward(difficulty)
local coins = difficultyModifier[difficulty] * rewardCoins
return coins
end
return RewardManagerlocal ServerStorage = game:GetService("ServerStorage")
-- 加载模块脚本
local RewardManager = require(ServerStorage.RewardManager)
-- 调用模块脚本中的函数
local coins = RewardManager.getCoinReward("easy")
print("应该奖励 " .. coins .. " 个金币")常见故障排除
这里的一些提示解决了使用模块脚本时常见的问题。请记住,模块脚本可能是一个复杂的话题,具有更多的细微差别。有关更多详细信息,请参阅此更技术性的指南 模块脚本。
问题: 获取包含 "Infinite yield possible" 或 "not a valid member" 的错误消息。
- 检查加载模块脚本的拼写。require() 必须包含模块脚本的确切路径和拼写,模块表的名称可能不同。
问题: 获取包含 "attempt to index global" 的错误消息。
- 在任何使用模块脚本的脚本中,确保使用函数 require() 加载它。如果没有,该脚本无法使用模块脚本中的函数和变量。
总结
模块脚本 在 Roblox 中是程序员用来组织和重用代码的一种方法。模块脚本通常存储在 ServerStorage 中(或用于基于客户端的交互时存储在 ReplicatedStorage 中)。从那里,其他脚本能够调用存储在该模块脚本中的函数和变量。
例如,一个游戏可能会因收集物体而奖励玩家积分。一个模块脚本可以处理给积分的代码。然后,不同类型物体的脚本可以直接调用模块脚本函数。这减少了在脚本之间重用代码的需要,使代码更易于理解和维护。