對於許多開發者來說,適應 Roblox 腳本的根本挑戰在於檔案位置和 Script.RunContext 屬性的重視。根據腳本類型、在 Explorer 中的位置和運行上下文,腳本的行為可能會非常不同。某些方法調用可能會失敗,遊戲中的物件可能無法訪問,或者腳本可能根本不會運行。
這種複雜性的原因在於 Roblox 遊戲默認為多人遊戲。腳本需要能夠僅在伺服器上運行、僅在客戶端上運行,或在兩者之間共享。隨著 Roblox 平台隨時間的演變,情況變得更加複雜。
腳本類型
Roblox 有三種類型的腳本:
- Script - 根據其位置和 Script.RunContext 屬性,在伺服器或客戶端運行的代碼。
- LocalScript - 僅在客戶端運行的代碼。沒有運行上下文。
- ModuleScript - 可以在其他腳本中重用的代碼。沒有運行上下文。
當你創建一個 Script 時,其默認運行上下文為 Legacy,這意味著它 a) 是伺服器端腳本,並且 b) 只有在伺服器容器中(例如 ServerScriptService 或 Workspace)時才會運行。
- 如果你將腳本的運行上下文更改為 Server,它現在也可以在 ReplicatedStorage 中運行,但我們不建議這樣做。該位置的內容會複製到客戶端,因此它不是伺服器端腳本的良好位置。
- 如果你將腳本的運行上下文更改為 Client,它可以在 ReplicatedStorage 中運行。它也可以在 StarterCharacterScripts 和 StarterPlayerScripts 中運行。不過,啟動容器會複製到客戶端,因此原始腳本 和 複製都會運行,這並不理想。
要更改腳本運行上下文,請在 Explorer 中選擇它,然後在 Properties 窗口中更改值。

建議
將一個 Script,其 RunContext 為 Client,放入 ReplicatedStorage 中。
將一個 Script,其 RunContext 為 Server,放入 ServerScriptService 中。
對於盡可能多的客戶端和伺服器代碼,使用 ModuleScripts。在你的客戶端腳本和伺服器腳本中要求這些模組。
這種方法為你的代碼提供了一個在客戶端和伺服器端的單一入口點,簡化了組織,並使隔離或禁用有問題的模組變得容易。為每個 ModuleScript 添加一個 start() 函數,以便在開始執行其代碼之前加載所有模組:
範例伺服器腳本--!strictlocal ServerScriptService = game:GetService("ServerScriptService")local SampleModule = require(ServerScriptService.SampleModule)local AnotherSampleModule = require(ServerScriptService.AnotherSampleModule)SampleModule.start()AnotherSampleModule.start()範例模組--!strictlocal CollectionService = game:GetService("CollectionService")local NPC_TAG = "npc"local SampleModule = {}local function setUpNpc(npc: Instance)-- 初始化每個 NPCendlocal function cleanUpNpc(npc: Instance)-- 當事件觸發時運行endfunction SampleModule.start() -- 將函數添加到表中-- 根據標籤的設置範例循環for _, npc in CollectionService:GetTagged(NPC_TAG) dosetUpNpc(npc)end-- 當事件觸發時運行函數CollectionService:GetInstanceAddedSignal(NPC_TAG):Connect(setUpNpc)CollectionService:GetInstanceRemovedSignal(NPC_TAG):Connect(cleanUpNpc)endreturn SampleModule要共享代碼,請在 ReplicatedStorage 中使用 ModuleScripts,並在你的客戶端腳本和伺服器腳本中要求它們。
如果你的遊戲需要,請在 ReplicatedFirst 中重複相同的模式,使用一個客戶端腳本和最少數量的 ModuleScripts 來實現加載畫面。要了解有關 ReplicatedFirst 的更多信息,請參見 複製順序。
請謹慎使用 LocalScripts。如果必須使用它們,請將它們放在 StarterCharacterScripts、StarterPlayerScripts、StarterGui 或 StarterPack 中。
這些容器中的腳本會克隆到玩家容器中,而不是從一個位置運行,這可能會使調試變得複雜。使用 ReplicatedStorage 來處理客戶端代碼,讓你可以在 Output 窗口中點擊行並轉到 ReplicatedStorage.YourScript(腳本的穩定位置),而不是 Players.YourName.PlayerScripts.YourLocalScript(腳本在運行時被複製到的短暫位置)。
避免將腳本直接附加到 Workspace 中的實例。相反,請 標記實例,並使用 CollectionService 從單個 ModuleScript 中處理它們。
主要例外是如果你在創作者商店中分發模型或包。在這種情況下,你可能需要在實例層次結構中包含腳本;為每個腳本指定一個 RunContext 以消除其運行方式的模糊性。明確設置此屬性使模型和包更有可能在各種位置正常工作。
範例專案結構
Plant 參考專案顯示了你如何在大型複雜遊戲中組織代碼。它將絕大多數代碼存儲為可重用的 ModuleScripts。
腳本位置
| Location | Description |
|---|---|
| Workspace | 代表遊戲的 3D 世界。可以運行直接附加到物件並控制其行為的伺服器腳本。 |
| ReplicatedFirst | 包含在其他任何物件之前複製到客戶端的物件。此位置非常適合顯示加載畫面所需的最小物件和客戶端腳本集。 |
| ReplicatedStorage | 包含複製到客戶端和伺服器的物件。此位置非常適合具有 Scripts 的 RunContext 為 Client 的客戶端 ModuleScripts,以及您希望在伺服器和客戶端上使用的 ModuleScripts。LocalScripts 不會從此位置運行。 |
| ServerScriptService | 包含伺服器腳本。此位置非常適合需要訪問伺服器端功能或物件的腳本,例如遊戲邏輯和雲端存儲。 |
| ServerStorage | 包含伺服器端物件。此位置非常適合不需要在玩家加入遊戲時立即複製到客戶端的大型物件。腳本不會從此位置運行,但您可以在此存儲伺服器端的 ModuleScripts。 |
| StarterPlayer ⟩ StarterCharacterScripts | 包含在角色生成時運行的 LocalScripts。 |
| StarterPlayer ⟩ StarterPlayerScripts | 包含在玩家加入遊戲時運行的 LocalScripts。 |
| StarterGui | 包含客戶端在加載遊戲時顯示的 GUI 元素。LocalScripts 可以從此位置運行。 |
| StarterPack | 通常只包含 Tools,但也可以包括用於設置玩家背包的 LocalScripts。 |
這張圖片顯示了哪些 Explorer 窗口位置可以包含客戶端腳本。請記住,ReplicatedFirst 和 ReplicatedStorage 可以包含 Scripts,其 RunContext 為 Client,而 Starter[] 容器應使用 LocalScripts。
