开发 / ROBLOX
Roblox Studio 中 Script、LocalScript 和 ModuleScript 应放在哪里
逐步检查脚本位置与 RunContext:服务器和客户端入口、LocalScript 副本、模块加载及容器对照表。
先确定由哪一侧执行 #
为每一小段代码明确任务。奖励规则需要服务器验证,本地界面展示属于客户端。共用函数可以放入模块,由合适的一侧调用。添加 Explorer 对象之前,先选择执行入口。
执行取决于对象类型、位置,以及普通 Script 的 RunContext。同样的代码在不同容器中可能表现不同。本练习先建立独立的服务器和客户端消息,再加载一个小模块。请使用单独的练习项目,方便确定每条消息对应哪个示例。
1. 启动普通服务器 Script #
在 ServerScriptService 中添加普通 Script,命名为 ServerStart。在 Properties 中将 RunContext 设为 Server。默认 Legacy 在这个容器中也适用,但明确设置 Server 更容易看出目的。确认脚本已启用。
把内容替换成第一个示例,打开 Output,启动带玩家的 Test。预期在服务器上下文看到 SERVER: ready。这证明执行到达了 print(),不是证明完整奖励系统已经完成。如果没有消息,先检查筛选器和对象位置,再修改代码。
print("SERVER: ready")2. 启动客户端 Script #
在 ReplicatedStorage 中添加普通 Script,命名为 ClientStart。必须明确把 RunContext 设为 Client,再粘贴第二个示例。仅把默认 Legacy 的 Script 放进这里,并不能自动建立客户端入口。
重新启动 Test。CLIENT: ready 应来自客户端,SERVER: ready 应来自服务器,它们是测试游戏的两侧。当前文档建议把这个客户端入口放在 ReplicatedStorage。不要把这个 Client 上下文的 Script 移到 StarterPlayerScripts:原件和副本可能都执行,造成不必要的重复。
print("CLIENT: ready")3. 使用 LocalScript 时注意副本 #
LocalScript 在客户端执行,没有 RunContext。进行独立练习时先停止 Test,暂时禁用 ClientStart,在 StarterPlayer → StarterPlayerScripts 中创建名为 LocalStart 的 LocalScript,使用 print("LOCAL: ready")。
测试后查找客户端消息。Starter 内容会复制到玩家,因此来源可能指向 Players → 玩家名 → PlayerScripts。这解释了运行路径为何不同于原始位置。仅储存在 ReplicatedStorage 中的 LocalScript,不会因为存在于那里就自动运行。
4. 从入口加载 ModuleScript #
停止测试,在 ReplicatedStorage 中创建 ModuleScript,准确命名为 PracticeModule。粘贴本节两个示例中的第一个。它返回包含 start() 的表。添加 ModuleScript 不会调用该函数,需要正在执行的代码加载它。
把 ServerStart 替换成本节第二个示例:查找模块,通过 require() 接收返回值,再调用 start()。新 Test 中应在服务器上下文看到 MODULE: started。WaitForChild 等待指定名称的对象,拼写错误不会创建缺失模块。请核对 Explorer 名称和代码中的 PracticeModule。
local PracticeModule = {}
function PracticeModule.start()
print("MODULE: started")
end
return PracticeModuleprint("SERVER: ready")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local practice = require(ReplicatedStorage:WaitForChild("PracticeModule"))
practice.start()5. 根据用途选择容器 #
可用下面的表作为初始结构。ServerScriptService 适合服务器入口;ReplicatedStorage 适合推荐的 Client 上下文 Script 和共用模块。客户端不需要的服务器专用模块可以留在 ServerScriptService。
位置与可见性是两个问题。ReplicatedStorage 内容会传到客户端,因此共用模块不能包含秘密,也不能代替购买和奖励的服务器验证。ServerStorage 保存服务器对象,普通 Script 在其中不会自动运行。应把执行入口放到适合运行的容器,而不是储存模型的地方。
| 类型与上下文 | 位置 | 用途 |
|---|---|---|
| Script · Server | ServerScriptService | 服务器入口 |
| Script · Client | ReplicatedStorage | 客户端入口 |
| LocalScript | StarterPlayer → StarterPlayerScripts | 客户端副本 |
| ModuleScript | ReplicatedStorage | 共用模块 |
| Script | ServerStorage | 储存;Script 不自动运行 |
6. 不启动时检查四项 #
检查准确类型、Explorer 路径、适用时的 RunContext,以及是否启用。模块还需找到调用 require() 的正在运行脚本。相似图标或相同名称不代表执行环境相同。
在入口加一条简短 print,清除 Output 文本筛选,并显示正确上下文。如果只有第一条标记,阅读两条之间的代码;两条都没有,先研究启动和消息显示。按来源阅读运行错误。随意移动所有文件会让原因更难定位。
7. 保存原件并重新检查 #
最终修改前停止 Test。如果游戏期间编辑了 PlayerScripts 中的 LocalScript 副本,把需要的修复应用到 StarterPlayerScripts 中的原件。测试对象在停止后恢复,仅修改临时副本可能无法保留到下一次运行。
回到主要示例时重新启用 ClientStart,不再需要独立练习时禁用 LocalStart。新 Test 中检查 SERVER: ready、CLIENT: ready 和服务器调用产生的 MODULE: started。保存项目。现在应能说出每条消息的类型、路径、上下文和调用方,再逐一安排真实功能。
原始资料
Roblox Creator HubRoblox Creator Hub · ModuleScript
Roblox Creator Hub · Output
Roblox Creator Hub · Testing modes