Tecniche e conversione

*Questo contenuto è tradotto usando AI (Beta) e potrebbe contenere errori. Per visualizzare questa pagina in inglese, clicca qui.

Questa guida delinea diverse tecniche per utilizzare lo streaming delle istanze in gioco in modo efficiente ed efficace. Anche se non esiste una soluzione "taglia unica" per progettare un gioco in streaming, seguire questi passaggi di alto livello ti porterà la maggior parte della strada.

Proprietà di streaming

Una volta che StreamingEnabled è attivato per l'oggetto Workspace in Studio, imposta le sue proprietà correlate ai seguenti valori raccomandati:

ProprietàRaccomandazione
EnableSLIMAvatarsUsa Enabled per rendere gli avatar rig standard come sostituti leggeri e animati quando appropriato. Vedi avatar SLIM per ulteriori informazioni.
ModelStreamingBehaviorUsa Improved per abilitare lo streaming più efficiente per Models con discendenti di BasePart.
StreamingIntegrityModeUsa PauseOutsideLoadedArea per bilanciare l'integrità del gameplay senza mettere in pausa inutilmente o troppo spesso.
StreamingMinRadiusUsa il valore predefinito di 64 per massimizzare quanto il motore può ridurre il gioco per dispositivi a bassa potenza.
StreamingTargetRadiusUsa il valore predefinito di 1024 per trovare un buon equilibrio tra visibilità per i giocatori su dispositivi ad alte prestazioni e un'impronta di memoria ragionevole.
StreamOutBehaviorUsa Opportunistic per consentire al client di raccogliere aggressivamente contenuti non utilizzati, riducendo significativamente l'uso della memoria e aiutando a prevenire crash per esaurimento della memoria.

Livello di dettaglio del modello

Model.LevelOfDetail aiuta a riempire i contenuti Model non streaming con mesh composite o impostore leggere, rendendo il mondo visivamente completo. SLIM (Modelli Leggeri Interattivi Scalabili) sono particolarmente efficaci, poiché i giocatori spesso non possono distinguere una mesh SLIM dall'originale completamente streaming.

Per i migliori risultati:

  • Raggruppa le parti che sono spazialmente e logicamente correlate, ad esempio tutte le parti di un'auto.
  • Imposta LevelOfDetail su SLIM sui modelli che contengono mesh e parti statiche. I modelli che vengono modificati durante il runtime o che riproducono animazioni non sono supportati.
  • Mantieni l'estensione spaziale di ciascun modello sotto ~64 stud cubici per aumentare la probabilità che l'intero modello effettivo venga streaming insieme. Se un modello ha estensioni molto grandi, suddividilo in modelli modulari più piccoli e applica un appropriato LevelOfDetail a ciascuno di essi.

Struttura del modello

Oltre a impostare il livello di dettaglio del modello, la struttura e le impostazioni dei tuoi Models hanno un impatto significativo su quanto bene lo streaming funzioni. Mentre costruisci o converti un gioco esistente:

  • Usa modelli atomici per raggruppamenti logici — Quando uno script ha bisogno di accesso a tutte le parti all'interno di un modello, imposta il suo ModelStreamingMode su Atomic. Questo consente agli script lato client di accedere in modo sicuro alle istanze all'interno del modello senza un uso eccessivo di WaitForChild() (anche se tali script devono comunque utilizzare WaitForChild() per l'intero modello atomico).

  • Minimizza i modelli persistenti — I modelli persistenti vengono caricati dopo l'accesso e non vengono mai streaming, occupando permanentemente memoria. Imposta il ModelStreamingMode di un modello su Persistent solo se deve rimanere disponibile e accessibile agli script in ogni momento.

  • Decomponi i modelli contenitore — Un modello non streaming comune è un singolo enorme Model che contiene molti NPC, oggetti o raggruppamenti simili. Sotto streaming, i modelli contenitore diminuiscono l'efficienza dello streaming e non sono ottimali per il livello di dettaglio del modello che funziona meglio con istanze strettamente raggruppate. Decomponi i modelli contenitore in modelli più piccoli con parti fisicamente vicine o logicamente correlate.

  • Appiattisci le gerarchie di modelli profondamente annidate — Annidare un modello persistente all'interno di un modello atomico costringe effettivamente il modello atomico a comportarsi come persistente. Gerarchie piatte sono più facili da comprendere sotto streaming.

Avatar SLIM

Gli avatar della piattaforma al di fuori dell'area attualmente streaming non sono visibili per impostazione predefinita, ma abilitando Workspace.EnableSLIMAvatars si rendono gli avatar rig standard come sostituti leggeri e animati quando appropriato. Effettivamente, il motore:

  • Rende una versione SLIM quando un modello avatar effettivo viene streaming.
  • Scambia tra rappresentazioni SLIM e a risoluzione completa in base alle risorse disponibili, anche all'interno del raggio di streaming.
  • Limita le animazioni SLIM in base all'importanza della scena e alla larghezza di banda disponibile.

Gli avatar SLIM supportano i personaggi giocatori con rig standard R15 con corpo, testa, abbigliamento a strati e accessori. Gli avatar R6, gli NPC e gli avatar con proporzioni personalizzate sono esclusi. Per l'elenco completo delle configurazioni di avatar supportate ed escluse, dati sulle prestazioni e suggerimenti per la risoluzione dei problemi, vedere avatar SLIM.

Modelli di script

I seguenti modelli di script sono i più comunemente influenzati dallo streaming. La strategia corretta dipende dall'intento del codice, quindi ogni modello elenca più opzioni dove appropriato.

Indice diretto ai discendenti

Indicizzare i discendenti di Workspace con l'operatore . genera un errore se qualsiasi istanza nel percorso non è attualmente streaming. Lo stesso vale per FindFirstChild(), FindFirstChildWhichIsA() e FindFirstChildOfClass() che restituiscono nil se il figlio non è stato streaming.

Ricerca Discendente
local house1 = workspace:FindFirstChild("House1") -- nil se "House1" non è stato streaming
local door = workspace.House1.Door -- Rotto se "House1" o "Door" non è stato streaming

Un modello simile è accedere direttamente ai discendenti di Humanoid o ad altri discendenti del personaggio all'interno di una connessione Player.CharacterAdded. Sotto streaming, il modello del personaggio è parentato a Workspace prima che tutti i suoi discendenti siano stati replicati, quindi l'indicizzazione diretta fallisce.

Discendenti del Personaggio
local Players = game:GetService("Players")
local player = Players.LocalPlayer
player.CharacterAdded:Connect(function(character)
local humanoid = character.Humanoid
end)

Se lo script non può progredire senza un'istanza, attendila con WaitForChild():

Ricerca Discendente
local house1 = workspace:WaitForChild("House1")
local door = house1:WaitForChild("Door")

Istanze inviate da remoto

Un segnale RemoteEvent/RemoteFunction e l'istanza a cui si riferisce viaggiano in modo indipendente, quindi il segnale può arrivare al client prima che l'istanza sia presente — o l'istanza potrebbe non essere mai presente. Due cause probabili includono:

  • Sotto streaming, potrebbe esserci un leggero ritardo tra quando una parte/modello viene creato sul server e quando viene replicato ai client. Effettivamente, una parte referenziata da un RemoteEvent/RemoteFunction potrebbe semplicemente non esistere ancora, anche all'interno di un'area streaming.

  • Inviare un riferimento a parte/modello dal server al client tramite un RemoteEvent o RemoteFunction richiede che l'istanza sia replicata al client ricevente. Inviare un percorso di istanza come stringa ha lo stesso problema, poiché il percorso potrebbe risolversi in una posizione non esistente sul client:

    Script Client
    local ReplicatedStorage = game:GetService("ReplicatedStorage")
    local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
    remoteEvent.OnClientEvent:Connect(function(data)
    local checkpoint = data.checkpoint -- Errori se "checkpoint" non è stato streaming
    local level = workspace.Levels[data.levelPath] -- Errori se il percorso non è stato streaming
    end)

Se lo script del client ricevente ha bisogno dell'istanza per procedere, includi WaitForChild() prima di usarla. Nota che questo può bloccarsi indefinitamente se l'istanza non viene mai streaming, quindi considera di aggiungere un timeout come secondo parametro di WaitForChild().

Desincronizzazione del client

La desincronizzazione lato client dovrebbe essere trattata come un'eccezione, non come un modello di design standard. Introdurre copie solo client o riparentare istanze localmente può creare seri problemi. Controlla il tuo codice per i luoghi che si basano su questi tipi di modifiche che persistono sul client.

Ad esempio, riparentare un'istanza localmente da ReplicatedStorage a Workspace può rendere quell'istanza idonea per essere streaming. Allo stesso modo, clonare un'istanza localmente (Instance:Clone()) da ReplicatedStorage in Workspace crea una copia solo client che non fa più parte del pipeline di replicazione del server e non riceverà aggiornamenti delle proprietà dall'istanza originale di proprietà del server.

Lo stesso concetto si applica quando si chiama Instance:Destroy() sul client per un oggetto di proprietà del server. Questo rimuove l'istanza localmente ma il server la possiede ancora, quindi verrà streaming di nuovo con il suo stato originale quando sarà idonea.

Streaming proattivo

Quando la prossima destinazione di un giocatore può essere anticipata, fai chiamate lato server a Player:RequestStreamAroundAsync() per streaming aree transitorie per il caricamento temporaneo, oppure usa Player:AddReplicationFocus() su base limitata per aree che dovrebbero rimanere caricate fino a quando non vengono esplicitamente rilasciate.

Ad esempio, quando un personaggio giocatore sta per teletrasportarsi cambiando CFrame in casa di un altro giocatore in una posizione distante, puoi pre-fetch l'area di destinazione per ridurre al minimo il pop-in e fornire una transizione più fluida. Il seguente script mostra come un evento remoto da client a server può essere attivato per spostare un personaggio giocatore utilizzando un metodo di pre-fetch. Se la richiesta di pre-fetch ha successo quando la funzione restituisce, il raggio minimo attorno alla posizione target dovrebbe essere presente sul client.

Script Server - Teletrasporta Personaggio Giocatore
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local teleportEvent = ReplicatedStorage:WaitForChild("TeleportEvent")
local function teleportPlayer(player, teleportTarget)
-- Richiedi streaming attorno alla posizione target
player:RequestStreamAroundAsync(teleportTarget)
-- Teletrasporta il personaggio
local character = player.Character
if character and character.Parent then
local currentPivot = character:GetPivot()
character:PivotTo(currentPivot * CFrame.new(teleportTarget))
end
end
-- Chiama la funzione di teletrasporto quando il client attiva l'evento remoto
teleportEvent.OnServerEvent:Connect(teleportPlayer)

Letture delle proprietà delle istanze

Una volta che un'istanza viene streaming, gli aggiornamenti delle sue proprietà non vengono più replicati a quel client. La lettura di proprietà come BasePart.Position continua a riuscire ma restituisce l'ultimo valore replicato che può essere arbitrariamente obsoleto.

local Players = game:GetService("Players")
local player = Players.LocalPlayer
-- La posizione potrebbe essere obsoleta se "target" è stato streaming
local dist = (target.Position - player.Character.HumanoidRootPart.Position).Magnitude

Sposta la logica sul server, poiché gli script lato server vedono tutte le istanze in ogni momento. Questa è generalmente l'opzione più affidabile per controlli di distanza e altre logiche sensibili alla posizione.

Attesa sul percorso critico

Alcuni giochi non streaming caricano la loro mappa clonandola da ReplicatedStorage in Workspace, quindi attendono che sia presente sul client prima di rimuovere uno schermo di caricamento e segnalare la prontezza. Sotto streaming questo si blocca indefinitamente — il personaggio del client non è ancora stato generato, quindi non c'è focalizzazione della replicazione, e l'istanza della mappa spaziale non viene mai streaming.

Sposta la logica dello schermo di caricamento in modo che non dipenda dalla presenza di un'istanza spaziale specifica, ad esempio segnalando la prontezza una volta che il personaggio è stato generato e l'area immediata è stata streaming.

Gestione del cambiamento del segnale

Segnali come Instance.ChildAdded/Instance.ChildRemoved e segnali di CollectionService come GetInstanceAddedSignal() o GetInstanceRemovedSignal() si attivano anche durante lo streaming in/out, indistinguibili da veri spawn/rimozioni. Gli script riceventi non possono distinguere la differenza dal segnale da solo, quindi la logica che presume che un segnale corrisponda a un evento "reale" deve essere aggiornata.

Controlla gli script per eventuali listener di segnali che potrebbero rompersi o cambiare significativamente quando attivati dallo streaming in e/o streaming out. Ad esempio, se riproduci audio o effetti visivi quando un NPC nemico appare inizialmente nel mondo, assegna a ciascun nemico un attributo come Spawned al primo spawn, e salta la riproduzione dello stesso audio/effetti nei futuri streaming in del nemico.

Tracciamento degli Attributi
local CollectionService = game:GetService("CollectionService")
local TAG_NAME = "Nemico"
CollectionService:GetInstanceAddedSignal(TAG_NAME):Connect(function(enemy)
if not enemy:GetAttribute("Spawned") then
-- Imposta l'attributo "Spawned" sul nemico per lo spawn iniziale
enemy:SetAttribute("Spawned", true)
-- Riproduci audio/effetti visivi per questo spawn iniziale
playSpawnEffects(enemy)
end
end)

Iterazione su collezioni

Le iterazioni di collezione lato client come Instance:GetChildren() e Instance:GetDescendants() restituiscono solo il sottoinsieme di discendenti streaming. Questo si applica anche quando il genitore stesso è sempre replicato, come una Folder direttamente sotto Workspace i cui discendenti spaziali vengono streaming in e out.

local Players = game:GetService("Players")
local player = Players.LocalPlayer
-- La cartella "Homes" è sempre replicata ma i suoi figli vengono streaming in e out
-- Questo ciclo potrebbe perdere case che non sono attualmente streaming
for _, home in workspace.Homes:GetChildren() do
if home.Settings.Owner.Value == player.Name then
return home
end
end

Se è necessaria un'enumerazione completa, esegui la scansione sul server e passa il risultato al giocatore tramite un RemoteEvent se necessario.

Query spaziali

Le query spaziali lato client come WorldRoot:Raycast(), WorldRoot:GetPartBoundsInBox() e Model:GetBoundingBox() riflettono solo contenuti streaming. Se questo sia un problema dipende da come viene utilizzata la query.

Usa il server per query il cui risultato deve riflettere il mondo intero, ad esempio un raycast che controlla se il giocatore ha linea di vista su un obiettivo distante.

Altri modelli

I seguenti modelli possono anche applicarsi e dovrebbero essere considerati con attenzione:

  • Un Sound o AudioPlayer parentato a un oggetto 3D si ferma quando quell'oggetto viene streaming. Per audio ambientale che dovrebbe persistere indipendentemente dallo streaming, parenta l'emettitore a un modello persistente o a un contenitore non streaming.

  • Oggetti UI in gioco come BillboardGui o SurfaceGui così come effetti visivi come Beams o Highlights il cui adornee o attacco viene streaming semplicemente smettono di rendere. Questo potrebbe essere il comportamento previsto, ma dovresti verificarlo.

  • Gli eventi BasePart.Touched, ProximityPrompts, DragDetectors, e ClickDetectors non operano per i giocatori il cui client non ha l'oggetto/il modello associato streaming. Se l'interazione deve essere possibile da qualsiasi distanza, il modello deve essere persistente o l'interazione deve avere un meccanismo diverso.

  • Per PathfindingService e il pathfinding lato client, il cercatore di percorso vede solo la geometria streaming sul client e potrebbe instradarsi attraverso ostacoli che esistono sul server. Vedi qui per strategie.

Condizioni di test realistiche

Una volta che gli script sono stati aggiornati, testa il gioco a fondo. I bug di streaming spesso si manifestano solo ai bordi dell'area streaming o durante le transizioni, quindi testare solo vicino allo spawn o al raggio target non è sufficiente.

  • Testa con Workspace.StreamingTargetRadius impostato al suo valore minimo (64). Alcuni bug di streaming appaiono solo quando l'area streaming è piccola.

  • Gioca attraverso i modelli di traversata completi del gioco, teletrasportati tra aree distanti e visita aree dopo averle lasciate. Queste sono le situazioni che esercitano di più lo streaming in e out.

  • Usa il sovrapposizione di debug dello streaming per monitorare le impostazioni di streaming attive, le regioni attualmente caricate e lo stato di streaming in tempo reale.

  • Controlla la finestra Output e la Console Sviluppatore per errori, poiché molti dei modelli di script producono errori piuttosto che comportamenti silenziosi errati. Presta particolare attenzione agli errori della forma attempt to index nil with ... che spesso indicano una chiamata mancante a WaitForChild().

  • Equipaggia e attiva Tools, spara armi e attiva diverse interazioni di gioco.

Abilità di conversione streaming AI

Per assistere con la conversione e l'ottimizzazione dello streaming, Roblox offre un'abilità di streaming AI, accessibile dal server MCP di Studio. L'abilità valuta automaticamente il tuo gioco, applica configurazioni raccomandate e risolve problemi di compatibilità, inclusi:


Per utilizzare l'abilità AI nel tuo gioco:

  1. IMPORTANTE
    Fai un backup del tuo gioco. Il processo di conversione può essere complesso, quindi dovresti sempre salvare un backup (File ⟩ Pubblica su Roblox Come) prima di eseguire l'abilità.

  2. Puoi eseguire questa abilità utilizzando qualsiasi LLM tu preferisca tramite il Protocollo di Contesto del Modello (MCP) in Studio. Si raccomandano modelli AI di fascia alta con ampie finestre di contesto; in Claude Opus, la conversione tipica richiede 20-30 minuti e utilizza circa 200.000 token di contesto.

    1. Apri il tuo gioco in Studio.
    2. Scarica l'abilità e, nel tuo client AI, apri la cartella decompressa (roblox-streaming-conversion) come progetto corrente.
    3. Esegui l'abilità con /rbx-convert-to-streaming.
    4. Come con qualsiasi output AI, verifica i risultati e metti alla prova il tuo gioco ampiamente in condizioni di test realistiche.
© 2026 Roblox Corporation. Roblox, il logo Roblox e Powering Imagination sono tra i nostri marchi registrati e non registrati negli Stati Uniti. e altri paesi.