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

模块脚本的结构
创建时,每个模块脚本都以以下代码开始:
local Module = {}return Module
这一行 local Module = {} 创建了一个表或代码容器,其中可以存储模块的共享函数和变量。这个表应重命名为模块的目的,例如 RewardManager 或 ParticleController。与其他变量(使用驼峰命名,如myVariable)不同,模块表推荐使用帕斯卡命名并以大写字母开头(MyModule)。
local RewardManager = {}return RewardManager
为了让其他脚本能够使用模块的非本地函数或变量,每个模块都以 return MyModule 结尾。每当另一个脚本尝试从模块获取代码时,返回会让该脚本访问存储在模块表中的代码。
向模块脚本添加内容
要向模块中添加可以在其他脚本中使用的函数或变量,输入模块表的名称,后跟一个点和函数或变量的名称,例如 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 示例
ModuleScript - 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 RewardManager
Script - TreasureChestScriptlocal 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 中)。在此之后,其他脚本能够调用存储在该模块脚本中的函数和变量。
例如,一个体验可能会因玩家收集物体而奖励积分。一个模块脚本可以处理给分的代码。然后,不同类型物体的脚本可以直接调用模块脚本函数。这减少了在脚本之间重用代码的需求,使代码更易于理解和维护。