此頁面描述了常見的效能問題及其緩解的最佳實踐。
腳本計算
在 Luau 代碼中,昂貴的操作需要更長的處理時間,因此可能會影響幀率。除非以並行方式執行,否則 Luau 代碼是同步運行的,並會阻塞主線程,直到遇到一個讓線程暫停的函數。
常見問題
- 對表結構的密集操作 - 複雜的操作,如序列化、反序列化和深度克隆,會產生高效能成本,特別是在大型表結構上。如果這些操作是遞歸的或涉及遍歷非常大的數據結構,這一點尤其如此。
緩解
- 在 RunService 事件上謹慎調用代碼,限制使用於高頻調用至關重要的情況(例如,更新相機)。您可以在其他事件中或在循環中以較低的頻率執行大多數其他代碼。
- 使用 task.wait() 將大型或昂貴的任務分解,以便在多個幀中分散工作。
- 確定並優化不必要的昂貴操作,並對於不需要訪問數據模型的計算密集型任務使用 多線程。
- 某些伺服器端腳本可以受益於 原生代碼生成,這是一個簡單的標誌,可以將腳本編譯為機器碼而不是字節碼。
- 如果您的伺服器在優化後仍然耗盡 CPU,您可以使用 計算的擴展服務 預留更多資源。
MicroProfiler 範圍
| 範圍 | 相關計算 |
| RunService.PreRender | 在 PreRender 事件上執行的代碼 |
| RunService.PreSimulation | 在 Stepped 事件上執行的代碼 |
| RunService.PostSimulation | 在 Heartbeat 事件上執行的代碼 |
| RunService.Heartbeat | 在 Heartbeat 事件上執行的代碼 |
有關使用 MicroProfiler 調試腳本的更多信息,請參見 debug 庫,其中包括標記特定代碼和進一步提高特異性的函數,例如 debug.profilebegin 和 debug.profileend。許多由腳本調用的 Roblox API 方法也有其自己的相關 MicroProfiler 標籤,可以提供有用的信號。
腳本內存使用
當您編寫的腳本消耗內存而垃圾收集器無法正確釋放時,可能會發生內存泄漏。泄漏在伺服器上特別普遍,因為它們可以持續在線多天,而客戶端會話則短得多。
在 開發者控制台 中,以下內存值可能表明需要進一步調查的問題:
- LuaHeap - 高或增長的消耗表明內存泄漏。
- InstanceCount - 實例數量持續增長表明您的代碼中對某些實例的引用未被垃圾收集。
- PlaceScriptMemory - 提供逐腳本的內存使用情況分析。
常見問題
保持連接的連接 - 引擎從不垃圾收集連接到實例的事件及其連接回調中引用的任何值。因此,事件的活動連接和連接實例中的代碼及引用的值,對於內存垃圾收集器來說是超出範圍的,即使事件已被觸發。
雖然當它們所屬的實例被銷毀時,事件會被斷開連接,但一個常見的錯誤是認為這適用於 Player 對象。在用戶離開遊戲後,引擎不會自動銷毀其代表的 Player 對象和角色模型,因此如果您不在腳本中斷開它們,則對 Player 對象和角色模型下的實例(例如 CharacterAdded)的連接仍然會消耗內存。這可能會導致伺服器上隨著數百名用戶進入和離開遊戲而產生非常顯著的內存泄漏。
表 - 將對象插入表中,但在不再需要時不將其刪除,會導致不必要的內存消耗,特別是對於跟踪用戶數據的表。例如,以下代碼示例在每次用戶加入時創建一個表以添加用戶信息:
示例local playerInfo = {}Players.PlayerAdded:Connect(function(player)playerInfo[player] = {} -- 一些信息end)如果您不在不再需要時刪除這些條目,則該表將繼續增長並隨著更多用戶加入會消耗更多內存。任何遍歷此表的代碼在表增長時也會變得計算上更昂貴。
緩解
為了清理所有使用的值以防止內存泄漏:
斷開所有連接 - 瀏覽您的代碼庫,確保每個連接都通過以下路徑之一進行清理:
- 使用 Disconnect() 函數手動斷開連接。
- 使用 Destroy() 函數銷毀事件所屬的實例。
- 銷毀連接回調所追溯的腳本對象。
在離開後刪除玩家對象和角色 - 啟用 Workspace.PlayerCharacterDestroyBehavior 以在用戶離開後自動銷毀玩家對象和角色模型。如果您願意,您也可以手動清理它們:
示例玩家和角色清理local Players = game:GetService("Players")Players.PlayerAdded:Connect(function(player)player.CharacterRemoving:Connect(function(character)task.defer(character.Destroy, character)end)end)Players.PlayerRemoving:Connect(function(player)task.defer(player.Destroy, player)end)
物理計算
過度的物理模擬可能是伺服器和客戶端每幀計算時間增加的主要原因。
常見問題
過度的物理時間步頻率 - 默認情況下,步進行為是 自適應模式,物理以 60 Hz、120 Hz 或 240 Hz 的頻率進行,具體取決於物理機制的複雜性。
也提供了一種固定模式,具有改進的物理準確性,強制所有物理組件以 240 Hz(每幀四次)進行步進。這會導致每幀計算量顯著增加。
模擬對象的過多數量或複雜性 - 模擬的 3D 組件越多,每幀的物理計算所需的時間就越長。通常,遊戲中會有不需要模擬的對象,或者會有比需要的約束和關節更多的機制。
過於精確的碰撞檢測 - 網格部件具有 CollisionFidelity 屬性,用於檢測碰撞,提供不同性能影響的多種模式。網格部件的精確碰撞檢測模式具有最高的性能成本,並且需要更長的計算時間。
緩解
固定不需要模擬的部件 - 鎖定所有不需要物理驅動的部件,例如靜態 NPC。
使用自適應物理步進 - 自適應步進動態調整物理計算的速率,允許在某些情況下減少物理更新的頻率。
減少機制複雜性
- 在可能的情況下,最小化組件中的物理約束或關節數量。
- 減少機制內的自我碰撞,例如通過對布娃娃肢體施加限制或無碰撞約束來防止它們相互碰撞。
減少對網格的精確碰撞保真度的使用
對於小型或不互動的對象,使用盒子保真度,因為用戶不會注意到差異。
對於小到中型的對象,根據形狀使用盒子或外殼保真度。
對於大型和非常複雜的對象,盡可能使用不可見部件構建自定義碰撞。
對於不需要碰撞的對象,禁用碰撞並使用盒子或外殼保真度,因為碰撞幾何仍然存儲在內存中。
您可以通過在 3D 視口的右上角小部件中切換 碰撞保真度 來在 Studio 中渲染碰撞幾何以進行調試。
或者,您可以將 CollisionFidelity=PreciseConvexDecomposition 過濾器應用於 Explorer,該過濾器顯示所有具有精確保真度的網格部件的計數,並允許您輕鬆選擇它們。
有關如何選擇平衡精度和性能要求的碰撞保真度選項的深入說明,請參見 設置物理和渲染參數。
MicroProfiler 範圍
| 範圍 | 相關計算 |
| physicsStepped | 整體物理計算 |
| worldStep | 每幀進行的離散物理步進 |
物理內存使用
物理運動和碰撞檢測會消耗內存。網格部件具有 CollisionFidelity 屬性,決定用於評估網格的碰撞邊界的方法。
常見問題
默認和精確的碰撞檢測模式消耗的內存顯著高於其他兩種低保真度碰撞形狀的模式。
如果您在 PhysicsParts 下看到高水平的內存消耗,您可能需要考慮減少對象的 碰撞保真度。
如何緩解
為了減少碰撞保真度使用的內存:
- 使用 CollisionFidelity 設置減少碰撞的保真度。Box 具有最低的內存開銷,而 Default 和 Precise 通常更昂貴。
- 對於任何小型固定部件,將其碰撞保真度設置為 Box 通常是安全的。
- 對於非常複雜的大型網格,您可能希望使用較小的對象構建自己的碰撞網格,並使用盒子碰撞保真度。
人形
Humanoid 是一個為玩家和非玩家角色 (NPC) 提供廣泛功能的類。雖然功能強大,但 Humanoid 會帶來顯著的計算成本。
常見問題
- 在 NPC 上啟用所有 HumanoidStateTypes - 保留某些 HumanoidStateTypes 啟用會產生性能成本。禁用對於您的 NPC 不需要的任何狀態。例如,除非您的 NPC 將要爬梯子,否則可以安全地禁用 Climbing 狀態。
- 在不需要的情況下使用 Humanoids - 靜態 NPC 通常不需要 Humanoid 類。
- 從伺服器播放大量 NPC 的動畫 - 在伺服器上運行的 NPC 動畫需要在伺服器上進行模擬並複製到客戶端。這可能是多餘的開銷。
- 執行不必要的大小和縮放變更 - 大小/縮放變更會導致 FastCluster 被重建。如果您看到與 FastCluster 相關的性能問題,請嘗試在遊戲過程中減少這一點。同樣,其他屬性變更也可能導致 FastCluster 被重建,因此一般來說,儘量減少這些變更。
緩解
- 在客戶端播放 NPC 動畫 - 在有大量 NPC 的遊戲中,考慮在客戶端創建 Animator 並在本地運行動畫。這減少了伺服器的負擔,並減少了不必要的複製需求。這還使得其他優化成為可能(例如僅為靠近角色的 NPC 播放動畫)。
- 使用性能友好的替代品來替代 Humanoids - NPC 模型不一定需要包含人形對象。
- 對於靜態 NPC,使用簡單的 AnimationController,因為它們不需要移動,只需播放動畫。
- 對於移動的 NPC,根據 NPC 的複雜性考慮實現自己的運動控制器並使用 AnimationController 進行動畫。
- 禁用未使用的人形狀態 - 使用 Humanoid:SetStateEnabled() 僅啟用每個人形所需的狀態。
- 對於頻繁重生的 NPC 模型進行池化 - 不要完全銷毀 NPC,而是將 NPC 發送到一個不活動的 NPC 池中。這樣,當需要重生新的 NPC 時,您可以簡單地重新激活池中的一個 NPC。這個過程稱為池化,最小化了角色需要實例化的次數。
- 僅在用戶附近生成 NPC - 當用戶不在範圍內時,不要生成 NPC,並在用戶離開範圍時將其剔除。
- 避免在實例化後對角色層次結構進行更改 - 對角色層次結構的某些修改會對性能產生重大影響。一些優化是可用的:
MicroProfiler 範圍
| 範圍 | 相關計算 |
| stepHumanoid | 人形控制和物理 |
| stepAnimation | 人形和動畫師動畫 |
| updateInvalidatedFastClusters | 與實例化或修改角色相關 |
渲染
客戶端每幀花費的時間中,有相當一部分用於渲染當前幀的場景。伺服器不進行任何渲染,因此本節僅針對客戶端。
繪製調用
繪製調用是引擎向 GPU 發送的渲染某些內容的一組指令。繪製調用具有顯著的開銷。通常,每幀的繪製調用越少,渲染一幀所花費的計算時間就越少。
您可以通過 Studio 中的 渲染統計 ⟩ 計時 項目查看當前發生的繪製調用數量。您可以通過按 ShiftF2 在客戶端查看 渲染統計。
在給定幀中需要繪製的對象越多,對 GPU 的繪製調用就越多。然而,Roblox 引擎利用一個稱為 實例化 的過程,將具有相同紋理特徵的相同網格合併為單個繪製調用。具體而言,當多個具有相同 MeshContent 的網格在單個繪製調用中處理時:
- 如果存在,則 SurfaceAppearances 相同,否則當 TextureContents 相同時。
- 當 SurfaceAppearance 和 MeshPart.TextureID 都不存在時,材料是相同的。
其他常見問題
過度的對象密度 - 如果大量對象集中在高密度中,則渲染該場景的該區域需要更多的繪製調用。如果您發現當查看地圖的某個部分時幀率下降,這可能是該區域對象密度過高的良好信號。
像貼花、紋理和粒子這樣的對象不易批處理,並會引入額外的繪製調用。在場景中對這些對象類型特別注意。特別是,對 ParticleEmitters 的屬性變更可能會對性能產生重大影響。
錯過實例化機會 - 通常,場景中會包含相同的網格重複多次,但每個網格的網格或紋理資產 ID 不同。這會阻止實例化,並可能導致不必要的繪製調用。
這個問題的常見原因是當整個場景一次性導入,而不是將單個資產導入到 Roblox 中,然後在導入後重複使用以組裝場景。
甚至像這樣的簡單腳本也可以幫助您識別使用不同網格 ID 的相同名稱的網格部件:
for _,descendant in workspace:GetDescendants() doif descendant:IsA("MeshPart") thenprint(descendant.Name .. ", " .. descendant.MeshId)endend輸出(啟用 堆疊行)可能看起來像這樣。重複的行表示重用相同的網格,這是好的。唯一的行不一定是壞的,但根據您的命名方案,可能表明遊戲中存在重複的網格:
LargeRock, rbxassetid://106420009602747 (x144) -- goodLargeRock, rbxassetid://120109824668127LargeRock, rbxassetid://134460273008628LargeRock, rbxassetid://139288987285823LargeRock, rbxassetid://71302144984955LargeRock, rbxassetid://90621205713698LargeRock, rbxassetid://113160939160788LargeRock, rbxassetid://135944592365226 -- all possible duplicates過度的對象複雜性 - 雖然繪製調用的數量不如重要,但場景中的三角形數量確實會影響渲染一幀所需的時間。場景中具有非常大量的非常複雜的網格是一個常見問題,過多的網格上設置 MeshPart.RenderFidelity 屬性為 Precise 也是如此。
過度的陰影投射 - 處理陰影是一個昂貴的過程,包含大量和高密度的光源物體(或受到陰影影響的小部件)的地圖可能會出現性能問題。
高透明度重繪 - 將部分透明的對象彼此放置在一起,迫使引擎多次渲染重疊的像素,這可能會影響性能。要了解如何識別和修復此問題,請參見 刪除分層透明度。
不必要的蒙皮 MeshPart 移動 - 沒有 Humanoid 的模型中的蒙皮 MeshParts 使用空間組織的 FastClusters 進行分組。當這些 MeshParts 移動時,必須不斷地將它們添加到這些空間集群中並從中移除,迫使集群重建並影響性能。
- 一個非常有效的解決方法是在模型中嵌入一個 Humanoid。Humanoid 的存在會覆蓋默認的空間聚類行為,強制整個模型使用單一的統一 FastCluster。因此,位置更新不再需要集群重建,從而減輕性能瓶頸。這種技術應僅保留給預期會移動的 MeshParts,因為它可能會引入內存開銷並抵消空間優化的好處。我們建議在進行這類更改後始終對您的遊戲進行性能分析。請參見 人形性能提示 獲取更多信息。
在 Model 中的部件過多 - 在模型中部件過多可能會導致重建更頻繁,因為部件的屬性變更可能導致需要完全重建。在使用 FastCluster 的模型中找到部件的正確平衡。
緩解
- 實例化相同的網格並減少唯一網格的數量 - 如果您確保所有相同的網格具有相同的基礎資產 ID,則引擎可以識別並在單個繪製調用中渲染它們。確保僅在地圖中上傳每個網格一次,然後在 Studio 中重複使用,而不是將大型地圖作為整體導入,這可能會導致相同的網格具有不同的內容 ID,並被引擎識別為唯一資產。包 是對象重用的有用機制。
- 剔除 - 剔除描述了消除不影響最終渲染幀的對象的繪製調用的過程。默認情況下,引擎跳過相機視野外的對象的繪製調用(視錐剔除)以及被其他對象遮擋的部件、網格和地形(遮擋剔除)。在某些情況下,例如室內環境,您可能能夠實施房間或傳送門系統,並手動剔除對象以進一步減少繪製調用或整體計算負載。
- 在適當的部件和光源上禁用陰影投射 - Roblox 引擎會隨著客戶端圖形質量級別的降低自動降低陰影質量,最終在質量級別低於 4 時完全禁用陰影。然而,您可以選擇性地禁用光源和部件上的陰影投射屬性,以提高性能,同時啟用陰影並增加陰影保持啟用的可能性。您可以在編輯時或在運行時進行的某些優化示例:
使用 BasePart.CastShadow 屬性禁用小部件的陰影投射,這些小部件的陰影不太可能可見。這種策略在應用於遠離用戶相機的部件時特別有效。
在可能的情況下禁用移動對象的陰影。
在不需要投射陰影的光源實例上禁用 Light.Shadows。
限制光源的範圍和角度。
使用更少的光源實例。
考慮在室內環境中禁用超出特定範圍的光源,或逐房間進行禁用。
MicroProfiler 範圍
| 範圍 | 相關計算 |
| Prepare and Perform | 整體渲染 |
| Perform/Scene/computeLightingPerform | 光網格和陰影更新 |
| LightGridCPU | 體素光網格更新 |
| ShadowMapSystem | 陰影映射 |
| Perform/Scene/UpdateView | 渲染準備和粒子更新 |
| Perform/Scene/RenderView | 渲染和後處理 |
網絡和複製
網絡和複製描述了數據在伺服器和連接的客戶端之間發送的過程。每幀都會在客戶端和伺服器之間發送信息,但較大的信息量需要更多的計算時間。
常見問題
過度的遠程流量 - 通過 RemoteEvent 或 RemoteFunction 對象發送大量數據或非常頻繁地調用它們,可能會導致每幀處理傳入數據包消耗大量 CPU 時間。常見錯誤包括:
- 每幀複製不需要複製的數據。
- 在用戶輸入時複製數據而沒有任何限制機制。
- 發送超過所需的數據。例如,在購買物品時發送玩家的整個庫存,而不僅僅是購買物品的詳細信息。
複雜實例樹的創建或刪除 - 當對伺服器上的數據模型進行更改時,會將其複製到連接的客戶端。這意味著在運行時創建和銷毀大型實例層次結構(如地圖)可能會非常耗費網絡資源。
這裡的常見罪魁禍首是由 動畫編輯器 插件在裝置中保存的複雜動畫數據。如果在遊戲發布之前未將其刪除,並且經常克隆動畫模型,則會不必要地複製大量數據。
伺服器端 TweenService - 如果在伺服器端使用 TweenService 對對象進行 tween,則每幀都會將 tweened 屬性複製到每個客戶端。這不僅會導致 tween 在客戶端延遲波動時顯得顫動,還會造成大量不必要的網絡流量。
緩解
您可以採用以下策略來減少不必要的複製:
- 避免通過遠程事件一次性發送大量數據。相反,僅以較低的頻率發送必要的數據。例如,對於角色的狀態,當其變更時複製,而不是每幀。
- 將複雜的實例樹分塊,例如地圖,並將其分成幾個部分加載,以便在多個幀中分配複製這些的工作。
- 清理動畫元數據,特別是裝置的動畫目錄,在導入後。
- 限制不必要的實例複製,特別是在伺服器不需要知道正在創建的實例的情況下。這包括:
- 視覺效果,例如爆炸或魔法法術爆炸。伺服器只需要知道位置以確定結果,而客戶端可以在本地創建視覺效果。
- 第一人稱物品視圖模型。
- 在客戶端而不是伺服器上對對象進行 tween。
MicroProfiler 範圍
| 範圍 | 相關計算 |
| ProcessPackets | 處理傳入網絡數據包,例如事件調用和屬性變更 |
| Allocate Bandwidth and Run Senders | 伺服器上相關的輸出事件 |
資產內存使用
創作者改善客戶端內存使用的最高影響機制是啟用 實例流式傳輸。
實例流式傳輸
實例流式傳輸選擇性地加載不需要的數據模型部分,這可以顯著減少加載時間並提高客戶端在內存壓力下防止崩潰的能力。
如果您遇到內存問題並且已禁用實例流式傳輸,請考慮更新您的遊戲以支持它,特別是如果您的 3D 世界很大。實例流式傳輸基於 3D 空間中的距離,因此較大的世界自然會受益更多。
如果啟用了實例流式傳輸,您可以增加其積極性。例如,考慮:
- 在可能的情況下減少使用 Enum.ModelStreamingMode.Persistent。如果您將其用作兼容性措施,則可能需要更新您的腳本。
- 減少 Workspace.StreamingMinRadius 和 Workspace.StreamingTargetRadius。
有關流式傳輸選項及其好處的更多信息,請參見 流式傳輸屬性。
其他常見問題
資產重複 - 一個常見錯誤是多次上傳相同的資產,導致不同的資產 ID。這可能導致相同的內容多次加載到內存中。
資產量過多 - 即使資產不相同,仍然存在錯過重用相同資產以節省內存的機會的情況。
音頻文件 - 音頻文件可能是內存使用的驚人貢獻者,特別是如果您一次性將所有音頻文件加載到客戶端,而不是僅加載您需要的部分。有關策略,請參見 加載時間。
高分辨率紋理 - 紋理的圖形內存消耗與磁碟上紋理的大小無關;紋理中的像素數量決定了內存使用。例如,1024x1024 像素的紋理消耗的圖形內存是 512x512 紋理的四倍。
上傳到 Roblox 的圖像會轉碼為固定格式,因此上傳與每像素字節數較少的顏色模型的圖像不會帶來內存好處。同樣,在上傳之前壓縮圖像或刪除不需要的圖像的 alpha 通道可以減少磁碟上的圖像大小,但不會改善內存使用。
隨著遊戲的加載,引擎會自動從較低質量的紋理開始,然後根據可用設備內存、距離相機、紋理佔用的屏幕空間量和其他因素逐步提高質量。即便如此,策略性地調整紋理大小可以改善遊戲中的內存使用。
緩解
僅上傳資產一次 - 在對象之間重用相同的資產 ID,並確保相同的資產(特別是網格和圖像)不會分別多次上傳。
查找並修復重複資產 - 查找多次上傳的相同網格部件和紋理,並使用不同的 ID。
- 雖然沒有 API 可以自動檢測資產的相似性,但您可以收集您位置中的所有圖像資產 ID(手動或使用腳本),下載它們,並使用外部比較工具進行比較。
- 對於網格部件,最佳策略是將唯一的網格 ID 按大小進行組織,以手動識別重複項。
- 不要為不同顏色使用單獨的紋理,而是上傳單個紋理,並使用 SurfaceAppearance.Color 屬性為其應用各種色調。
分別導入地圖資產 - 不要一次性導入整個地圖,而是單獨導入和重建地圖中的資產。導入器不會進行任何網格的去重,因此如果您導入一個大型地圖,其中有很多單獨的地板瓷磚,每個瓷磚都會作為單獨的資產導入(即使它們是重複的)。這可能會導致性能和內存問題,因為每個網格都被視為單獨的,並佔用內存和繪製調用。
限制圖像的像素數量,不超過必要的數量。除非圖像佔用屏幕上的大量物理空間,否則通常最多需要 512x512 像素。大多數小型圖像應小於 256x256 像素。
使用修整圖以確保在 3D 地圖中最大限度地重用紋理。要了解如何創建修整圖的步驟和示例,請參見 創建修整圖。
您還可以考慮使用精靈圖來將許多較小的 UI 圖像作為單個圖像加載。然後,您可以使用 ImageLabel.ImageRectOffset 和 ImageLabel.ImageRectSize 來顯示圖像的一部分。
加載時間
在玩家開始遊玩之前,客戶端必須接收 ReplicatedFirst 和 ReplicatedStorage 中的所有內容、Workspace 的初始內容以及您的腳本預加載的任何資產。客戶端在此期間需要下載和處理的內容越多,玩家等待的時間就越長。要了解加入過程中的每個步驟,請參見 識別性能問題。
常見問題
ReplicatedStorage 中的內容過多 - ReplicatedStorage 中的所有內容在玩家可以看到或與任何內容互動之前都會複製到每個客戶端,無論客戶端是否立即需要它。免費模型和繼承的資產可能會悄然增加大量內容。
重的 ReplicatedFirst 內容 - ReplicatedFirst 在其他任何內容之前複製,主要用於保存自定義加載屏幕。每個額外的資產或腳本都會延遲主要複製階段的開始。
過度使用 PreloadAsync() - 許多遊戲實現自定義加載屏幕,並使用 ContentProvider:PreloadAsync() 請求資產,以便在後台下載圖像、聲音和網格。這種方法確保遊戲的重要部分完全加載而不會出現突入,但一個常見的錯誤是預加載的資產超過實際需要的數量。
一個不良做法的例子是加載整個 Workspace。雖然這可能防止紋理突入,但它會顯著增加加載時間。
另一個類似的做法是利用 ContentProvider.RequestQueueSize 來確保所有請求的資產都已加載完成。然而,這會帶來同樣的問題,即顯著增加加載時間,同時由於其波動性,這也是一種不可靠的方法。
昂貴的啟動腳本 - 在加入過程中運行的 LocalScripts 中的重型腳本執行,例如同步加載大型數據結構,會延遲從複製到可玩狀態的過渡。
緩解
啟用實例流式傳輸 - 流式傳輸僅在玩家初次加入時發送靠近玩家生成點的世界部分,然後隨著玩家在遊戲中移動逐步流式傳輸其餘部分。對於尚未使用流式傳輸的遊戲,流式傳輸是減少加載時間的最有效方法之一。對於新地點,流式傳輸默認啟用。要了解設置步驟、屬性參考和遷移指導,請參見 實例流式傳輸。
保持 ReplicatedStorage 精簡 - 僅存儲客戶端在加入時需要的內容,例如 ModuleScripts 的共享,這些是 LocalScripts 所需的。將不立即需要的大型模型、音頻和其他資產移至 ServerStorage,並在玩家需要時再移至客戶端。定期審核 ReplicatedStorage 中您不再使用的內容。
保持 ReplicatedFirst 精簡 - 將 ReplicatedFirst 限制為加載屏幕所需的內容,例如基本 UI 元素,而不是大型紋理或 3D 模型,並避免在從中運行的腳本中進行重計算。要了解如何構建自定義加載屏幕,包括何時調用 ReplicatedFirst:RemoveDefaultLoadingScreen(),請參見 加載屏幕。
僅預加載必要的資產 - 僅在必要的情況下使用 ContentProvider:PreloadAsync(),這些情況包括:
- 加載屏幕中的圖像。
- 遊戲菜單中的重要圖像,例如按鈕背景和圖標。
- 開始或生成區域中的重要資產。
如果您必須加載大量資產,我們建議您提供一個 跳過加載 按鈕。
推遲非必要的啟動工作 - 僅在玩家尚未到達的內容首次需要時加載,例如他們尚未打開的 UI 面板。對於必須早期發生的初始化工作,將其分散到多個幀中,而不是一次性運行所有工作。要了解技術,請參見 腳本計算。