Diffusion en instance

*Ce contenu est traduit en utilisant l'IA (Beta) et peut contenir des erreurs. Pour consulter cette page en anglais, clique ici.

Le streaming d'instance en expérience permet à l'Engine Roblox de charger et décharger dynamiquement du contenu 3D et des instances associées dans des régions du monde .Cela peut améliorer l'expérience globale du joueur de plusieurs façons, par exemple :

  • Temps d'adhésion plus rapides — Les joueurs peuvent commencer à jouer dans une partie du monde pendant que plus du monde se charge en arrière-plan.
  • Efficiency mémoire — Les expériences peuvent être jouées sur des appareils avec moins de mémoire puisque le contenu est diffusé dynamiquement à l'intérieur et à l'extérieur.Des mondes plus immersifs et détaillés peuvent être joués sur une plus grande gamme d'appareils.
  • Amélioration des performances — Meilleurs taux de cadence et performances, car le serveur peut passer moins de temps et de bande passante à synchroniser les modifications entre le monde et les joueurs qui s'y trouvent.Les clients passent moins de temps à mettre à jour des instances qui ne sont pas actuellement pertinentes pour le joueur.
  • Niveau de détail — Les modèles distants et le terrain restent visibles même lorsqu'ils ne sont pas diffusés aux clients, en maintenant l'expérience optimisée sans sacrifier entièrement les images de fond.

Activer le streaming

La diffusion en instance est activée via la propriété StreamingEnabled de l'objet Espace de travail dans Studio.Cette propriété ne peut pas être définie dans un script.La diffusion en continu est activée par défaut pour les nouveaux endroits créés dans Studio.

The Properties window with the StreamingEnabled property enabled.

Une fois activé, il est recommandé que vous adhériez aux pratiques suivantes :

  • Comme les clients n'auront généralement pas tout le Workspace disponible localement, utilisez l'outil/API approprié pour vous assurer que des instances existent avant d'essayer d'y accéder dans un LocalScript .Par exemple, utilisez les contrôles de diffusion en continu par modèle, détecter la diffusion en continu d'instance ou utilisez WaitForChild() sur les objets qui peuvent ne pas exister.
  • Minimiser le placement du contenu 3D en dehors de Workspace .Le contenu dans des conteneurs tels que ReplicatedStorage ou ReplicatedFirst n'est pas éligible au streaming et peut avoir un impact négatif sur le temps de jointure et l'utilisation de la mémoire.
  • Si vous déplacez le personnage d'un joueur en définissant son CFrame, faites-le à partir d'une demande côté serveur Script et utilisez les demandes de diffusion en continu pour charger plus rapidement les données autour de la nouvelle position du personnage.
  • Définissez manuellement la ReplicationFocus du joueur seulement dans des situations uniques telles que dans les expériences qui n'utilisent pas un Player.Character .Dans ces cas, assurez-vous que le focus est près de l'objet(s) que le joueur contrôle pour assurer le maintien du flux de contenu autour du point d'interaction du joueur.

Comportement technique

Diffusion dans

Par défaut, lorsqu'un joueur rejoint une expérience avec le streaming d'instance activé, les instances dans le Workspace sont répliquées au client, excluant ce qui suivre:

Ensuite, pendant le partie, le serveur peut diffuser les instances nécessaires au client, comme elles sont nécessaires.

Diagram showing when various instances and their descendants in the Workspace stream in.
1 Le terrain est traité de manière unique, puisque l'instance se réplique au client lorsque l'expérience se charge, mais les régions de terrain ne se diffusent que lorsqu'elles sont nécessaires

Comportement du modèle

Modèles définis sur un comportement non par défaut comme le flux atomique sous des règles spéciales comme décrit dans les contrôles de flux par modèle.Cependant, les modèles par défaut (non atomiques) sont envoyés différemment en fonction de si ModelStreamingBehavior est réglé sur Défaut ( Héritage ) ou Amélioré .

The Properties window with the ModelStreamingBehavior property set to Default.

Lorsque ModelStreamingBehavior est défini sur Défaut / Héritage , le conteneur Model et ses descendants non spatiaux tels que Scripts se répliquent au client lorsque le joueur rejoint.Ensuite, lorsque c'est éligible, les descendants du modèlisationBasePart descendent.

Diagram showing default model stream in behavior.

Diffuser en sortie

Pendant le partie, un client peut diffuser (éliminer des régions du joueur Workspace ) et le BaseParts qu'il contient, en fonction du comportement défini par StreamOutBehavior.Le processus commence par les régions les plus éloignées du personnage du joueur (ou ReplicationFocus ) et se déplace plus près si nécessaire.Les régions situées à l'intérieur de la portée StreamingMinRadius ne sont jamais diffusées.

Lorsqu'une instance est diffusée, elle est parentée à nil afin que tout état Luau existant se reconnecte si l'instance se reconnecte.Par resultats, l'élimination des signaux tels que ChildRemoved ou DescendantRemoving feu sur son parent ou ancêtre , mais l'instance elle-même n'est pas détruite dans le même sens qu'un appel Instance:Destroy() .

Pour anticiper davantage le flux sortant, examinez ces scénarios :

ScénarioExempleComportement de diffusion en continu
Une partie est créée localement via Instance.new() dans un LocalScript .Dans un jeu « capture the indicateur, marquer», vous créez et attachez des pièces de casque bleu à tous les joueurs de l'équipe bleue via un LocalScript .La partie n'est pas répliquée sur le serveur, et elle est exemptée de sortie en continu à moins que vous ne la rendiez une descendant d'une partie qui existe sur le serveur, comme une partie dans le modèlisationde personnage d'un joueur.
Une partie est clonée localement à partir de ReplicatedStorage à travers Instance:Clone() dans un LocalScript .Un personnage sorcier lance un sort en activant un Tool , sur lequel un objet incluant plusieurs effets spéciaux est cloné à partir de ReplicatedStorage et parenté à l'espace de travail à la position du magicien.La partie n'est pas répliquée sur le serveur, et elle est exemptée de sortie en continu à moins que vous ne la rendiez une descendant d'une partie qui existe sur le serveur.
Une partie est réparée de ReplicatedStorage à l'espace de travail via un LocalScript .Un « chapeau de sorcier » est stocké dans ReplicatedStorage .Lorsqu'un joueur choisit de jouer dans l'équipe du sorcier, le chapeau est déplacé dans son modèle de personnage via un LocalScript .La partie reste éligible pour être diffusée puisqu'elle provient du serveur et a été répliquée à ReplicatedStorage .Évitez ce modèle car il provoque un désynchronisme entre le client et le serveur, et la partie peut s'écouler ; au lieu de cela, clonez la partie.

Comportement du modèle

Si vous définissez ModelStreamingBehavior à amélioré , le moteur peut diffuser par défaut ( non atomique ) des modèles lorsqu'ils sont éligibles à être diffusés, potentiellement libérant de la mémoire sur le client et réduisant le nombre d'instances qui ont besoin de mises à jour de propriété.

The Properties window with the ModelStreamingBehavior property set to Improved.

Sous amélioré le comportement de streaming du modèle, le streaming hors de par défaut ( non atomique ) modèles est basé sur le fait que le modèle soit spatial (contient descendants) ou non spatial (ne contient pas de descendants ).

  • Un modèle spatial ne s'écoule complètement que lorsque son dernier descendant BasePart descendant s'écoule, car certaines des parties spatiales du modèlisationpeuvent être près du focus du joueur/réplication et d'autres loin.
  • Un modèle non spatial ne s'écoule que lorsqu'un ancêtre s'écoule, équivalent au comportement de sortie hérité.

Assemblages et mécanismes

Lorsque au moins une partie d'une assemblage est éligible pour le streaming, toutes les parties de l'assemblage sont également diffusées.Cependant, une assemblée ne diffusera pas hors jusqu'à ce que toutes ses parties soient éligibles à la diffusion.Pendant la diffusion en continu, l'ensemble des Constraints et Attachments descendants de BaseParts et atomiques ou persistants Models fluxégalement, aidant à garantir des mises à jour de physique cohérentes sur les clients.

Notez que les assemblages avec des parties ancrées sont traités légèrement différemment des assemblages avec uniquement des parties non ancrées :

Composition de l'assemblageComportement de diffusion en continu
Parties non ancrées uniquementL'ensemble de l'assemblage est envoyé comme une unité atomique.
Partie racine ancrée Seules les parties, les pièces jointes et les contraintes nécessaires pour lier les parties diffusées à la partie racine sont diffusées ensemble.

Retard de calage

Il peut y avoir un léger retard de ~10 millisecondes entre le moment où une partie est créée sur le serveur et le moment où elle est répliquée aux clients.Dans chacun des scénarios suivants, vous devrez peut-être utiliser WaitForChild() et d'autres techniques plutôt que de supposer que les événements et les mises à jour de propriété se produisent toujours en même temps que la diffusion en partie.

ScénarioExempleComportement de diffusion en continu
Un LocalScript fait une demande RemoteFunction au serveur pour créer une partie.Un joueur active un Tool localement pour générer une partie sur le serveur que tous les joueurs peuvent voir et interagir avec.Lorsque la fonction à distance revient au client, la partie peut encore n'exister pas, même si la partie est proche du focus du client et dans une zone diffusée.
Une partie est ajoutée à un modèle de personnage sur le serveur via un Script et un RemoteEvent est tiré vers un client.Lorsqu'un joueur rejoint l'équipe de police, une partie de « badge de police » stockée dans ServerStorage est clonée et attachée au modèlisationde personnage du joueur.Un RemoteEvent est tiré et reçu par le client de ce joueur afin de mettre à jour un élément d'interface utilisateur locale.Bien que le client reçoive le signal d'événement, il n'y a aucune garantie que la partie ait déjà été diffusée à ce client.
Une partie se heurte à une région invisible sur le serveur et déclenche un RemoteEvent sur le client.Un joueur frappe un ballon de football dans le but, déclenchant un événement « but marqué ».D'autres joueurs qui sont proches de l'objectif peuvent voir l'événement "but marqué" avant que la balle ne leur soit diffusée.

Propriétés de diffusion en continu

Les propriétés suivantes contrôlent la manière dont le streaming d'instance s'applique à votre expérience.Toutes ces propriétés sont non scriptables et doivent être définies sur l'objet Espace de travail dans Studio.

The Properties window with the ModelStreamingBehavior, StreamingIntegrityMode, StreamingMidRadius, StreamingTargetRadius, and StreamOutBehavior property highlighted.

Comportement de streaming de modèle

Contrôle si les modèles par défaut ( non atomiques ) sont répliqués lorsqu'un joueur rejoint, ou sont envoyés seulement lorsque nécessaire.Si cette propriété est définie sur amélioré , les modèles dans Workspace ne seront envoyés aux clients que lorsque nécessaire, ce qui peut accélérer le temps de join.Voir comportement technique pour plus de détails.

Mode intégrité de streaming

Votre expérience peut se comporter de manières non intentionnelles si un joueur se déplace dans une région du monde qui n'a pas été diffusée à eux.La fonctionnalité intégrité de diffusion offre un moyen d'éviter ces situations potentiellement problématiques.Veuillez consulter la documentation Enum.StreamingIntegrityMode pour plus de détails.

Rayon de streaming minimum

La propriété StreamingMinRadius indique le rayon autour du personnage du joueur (ou ReplicationFocus ) dans lequel les instances se diffusent en priorité la plus élevée.Il faut faire attention lors de l'augmentation de la valeur par défaut, car cela nécessitera plus de mémoire et plus de bande passante du serveur au détriment d'autres composants.

Rayon cible de streaming

La propriété StreamingTargetRadius contrôle la distance maximale à partir du personnage du joueur (ou ReplicationFocus ) dans lequel les instances se diffusent.Notez que le moteur est autorisé à conserver des instances précédemment chargées au-delà du rayon cible, mémoire permettant.

Un plus petit StreamingTargetRadius réduit la charge du serveur, car le serveur ne diffusera pas dans des instances supplémentaires au-delà de la valeur définie.Cependant, le rayon cible est également la distance maximale à laquelle les joueurs pourront voir tous les détails de votre expérience, vous devez donc choisir une valeur qui crée un bon équilibre entre ces derniers.

Comportement de StreamOut

La propriété StreamOutBehavior définit le comportement de sortie en continu selon l'une des valeurs suivantes :

ParamètreComportement de diffusion en continu
Par défaut Comportement par défaut, actuellement identique à LowMemory .
Mémoire faible Le client ne diffuse que des parties dans une situation de faible mémoire et peut supprimer le contenu 3D jusqu'à ce que se présente le rayon minimum.
Opportuniste Les régions au-delà de StreamingTargetRadius peuvent être supprimées sur le client même lorsqu'il n'y a pas de pression mémoire.Dans ce mode, le client n'enlève jamais d'instances plus proches que le rayon cible, sauf dans les situations de faible mémoire.

contrôlesde diffusion en continu par modèle

Au niveau mondial, la propriété ModelStreamingBehavior vous permet de contrôler la façon dont les modèles sont diffusés en rejoignant.En outre, pour éviter les problèmes de streaming sur une base par modèle et minimiser l'utilisation de WaitForChild() , vous pouvez personnaliser la façon dont Models et leurs descendants diffusent à travers leur propriété ModelStreamingMode.

The Properties window with the ModelStreamingMode property set to Default. The property is also highlighted.

Par défaut / nonatique

Lorsqu'un Model est défini sur Défaut ou Nonatique , le comportement de streaming varie en fonction de si ModelStreamingBehavior est défini sur Défaut ( Héritage ) ou Amélioré .

Comportement de streaming de modèleComportement technique
Par défaut ( Héritage )Le modèle est répliqué lorsqu'un joueur rejoint.Cela peut potentiellement entraîner plus d'instances envoyées pendant le chargement, plus d'instances stockées en mémoire et une complexité supplémentaire pour les scripts qui souhaitent accéder aux descendants du modèlisation.Par exemple, un séparé LocalScript devra utiliser WaitForChild() sur un descendant BasePart à l'intérieur du modèlisation.
Amélioré Le modèle n'est envoyé que lorsque cela est nécessaire, ce qui peut accélérer les temps de jointure potentiellement.

Voir comportement technique pour plus de détails.

Atomique

Si un Model est modifié en atomique , tous ses descendants sont diffusés ensemble lorsqu'un descendant BasePart est éligible.Par resultats, un séparé LocalScript qui doit accéder aux instances dans le modèle devrait utiliser WaitForChild() sur le modèle lui-même, mais pas sur un descendant MeshPart ou Part puisqu'ils sont envoyés aux côtés du modèlisation.

Un modèle atomique n'est diffusé que lorsque toutes ses parties descendantes sont éligibles à la diffusion, à ce moment-là, le modèle entier diffuse ensemble.Si seules certaines parties d'un modèle atomique sont généralement diffusées, le modèle entier et ses descendants restent sur le client.

A diagram showing Atomic model streaming along with children.
Lecteur localScript

local Workspace = game:GetService("Workspace")
-- Le modèle atomique n'existe pas au moment du chargement ; utilisez WaitForChild()
local model = Workspace:WaitForChild("Model")
-- Les parties descendantes s'écoulent avec le modèle et sont immédiatement accessibles
local meshPart = model.MeshPart
local part = model.Part

Persistant

Les modèles persistants ne sont pas soumis à un streaming normal entrante ou sortante. Elles sont envoyées comme une unité atomique complète peu après que le joueur ait rejoint et avant que l'événement Workspace.PersistentLoaded ne se déclenche.Les modèles persistants et leurs descendants ne sont jamais diffusés, mais pour gérer en toute sécurité la diffusion dans un modèle séparé LocalScript, vous devez utiliser WaitForChild() sur le modèle parent, ou attendre que l'événement PersistentLoaded se lancer.

A diagram showing Persistent model streaming along with children.
Lecteur localScript

local Workspace = game:GetService("Workspace")
-- Le modèle persistant n'existe pas au moment du chargement ; utilisez WaitForChild()
local model = Workspace:WaitForChild("Model")
-- Les parties descendantes s'écoulent avec le modèle et sont immédiatement accessibles
local meshPart = model.MeshPart
local part = model.Part

PersistantParJoueur

Les modèles définis sur PersistantPerPlayer se comportent de la même manière que Persistant pour les joueurs qui ont été ajoutés en utilisant Model:AddPersistentPlayer() .Pour les autres joueurs, le comportement est le même que atomique .Vous pouvez annuler un modèle de la persistance du joueur via Model:RemovePersistentPlayer() .

Demander la diffusion en continu de la zone

Si vous définissez le CFrame d'un personnage de joueur à une région qui n'est pas actuellement chargée, pause de streaming se produit, si activé.Si vous savez que le personnage se déplacera vers une zone spécifique, vous pouvez appeler Player:RequestStreamAroundAsync() pour demander au serveur d'envoyer des régions autour de cet emplacement au client.

Les scripts suivants montrent comment déclencher un événement distant client-serveur pour téléporter un joueur dans un emplacement, en produisant à la demande de diffusion avant de déplacer le personnage vers une nouvelle .

Script - Téléporter le personnage du joueur

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local teleportEvent = ReplicatedStorage:WaitForChild("TeleportEvent")
local function teleportPlayer(player, teleportTarget)
-- Demander un streaming autour de la localisation cible
player:RequestStreamAroundAsync(teleportTarget)
-- Personnage de téléportation
local character = player.Character
if character and character.Parent then
local currentPivot = character:GetPivot()
character:PivotTo(currentPivot * CFrame.new(teleportTarget))
end
end
-- Appeler la fonction de téléportation lorsque le client lance l'événement distant
teleportEvent.OnServerEvent:Connect(teleportPlayer)
LocalScript - Événement de feu à distance

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local teleportEvent = ReplicatedStorage:WaitForChild("TeleportEvent")
local teleportTarget = Vector3.new(50, 2, 120)
-- Lancer l'événement distant
teleportEvent:FireServer(teleportTarget)

Détecter le streaming d'instance

Dans certains cas, il est nécessaire de détecter quand un objet se diffuse ou se réagit à un événement.Un modèle utile pour la détection de streaming est le suivant :

  1. En utilisant la section Balises des propriétés d'une instance, ou l'éditeur de balises de Studio, attribuez une balise logique à tous les objets affectés.

  2. À partir d'un seul LocalScript , détectez quand un objet étiqueté s'écoule à l'intérieur ou à l'extérieur via GetInstanceAddedSignal() et GetInstanceRemovedSignal() , puis gérer l'objet en conséquence.Par exemple, le code suivant ajoute des objets étiquetés Light dans une boucle "flicker" lorsqu'ils sont diffusés et les supprime lorsqu'ils sont diffusés.

    LocalScript - Détection de diffusion en continu du service de collection

    local CollectionService = game:GetService("CollectionService")
    local tagName = "FlickerLightSource"
    local random = Random.new()
    local flickerSources = {}
    -- Détecter actuellement et de nouvelles parties étiquetées en streaming entrante ou sortante
    for _, light in CollectionService:GetTagged(tagName) do
    flickerSources[light] = true
    end
    CollectionService:GetInstanceAddedSignal(tagName):Connect(function(light)
    flickerSources[light] = true
    end)
    CollectionService:GetInstanceRemovedSignal(tagName):Connect(function(light)
    flickerSources[light] = nil
    end)
    -- Boucle de scintillement
    while true do
    for light in flickerSources do
    light.Brightness = 8 + random:NextNumber(-0.4, 0.4)
    end
    task.wait(0.05)
    end

Personnaliser l'écran de pause

La propriété Player.GameplayPaused indique l'état de pause actuel du joueur.Cette propriété peut être utilisée avec une connexion GetPropertyChangedSignal() pour montrer ou masquer une interface utilisateur graphiquepersonnalisée.

Lecteur localScript

local Players = game:GetService("Players")
local GuiService = game:GetService("GuiService")
local player = Players.LocalPlayer
-- Désactiver la pause modal par défaut
GuiService:SetGameplayPausedNotificationEnabled(false)
local function onPauseStateChanged()
if player.GameplayPaused then
-- Afficher l'interface utilisateur graphiquepersonnalisée
else
-- Masquer l'interface utilisateur graphiquepersonnalisée
end
end
player:GetPropertyChangedSignal("GameplayPaused"):Connect(onPauseStateChanged)

Niveau de détail du modèle

Lorsque le streaming est activé, Models en dehors de la zone diffusée actuellement ne sera pas visible par défaut.Cependant, vous pouvez instruire le moteur de rendre des mailles «imposteur» de résolution inférieure pour les modèles qui ne sont pas présents sur les clients via la propriété LevelOfDetail de chaque modèlisation.

LevelOfDetail property indicated for Model instance
A globe model displays in its actual level of detail.

Modèle actuel
>

The same globe model displays as a low resolution imposter mesh with rough edges that obscure the globe's details.

Faible résolution du maillage "imposteur"
>

Définition du modèleComportement de diffusion en continu
StreamingMesh Active la génération asynchrone d'un maillage imposteur à afficher lorsque le modèle n'est pas présent sur les clients.
Désactivé / Automatique Le modèle disparaît lorsqu'il est en dehors du rayon de diffusion.

Lors de l'utilisation de mailles d'imposteur, notez ce qui suivre:

  • Les mailles d'imposteur sont conçues pour être vues à 1024 mètres de la caméra ou plus loin.Si vous avez réduit StreamingTargetRadius à une valeur beaucoup plus petite comme 256, les mailles d'imposteur peuvent ne pas être visuellement acceptables pour le modèle qu'elles remplacent.
  • Si un modèle et ses modèles descendants sont tous définis sur StreamingMesh , seul le modèle ancestral de niveau supérieur est rendu en tant que maillage imposteur, enveloppant toutes les géométries sous l'ancêtre ainsi que ses modèles descendants.Pour une meilleure performance, il est recommandé d'utiliser désactivé pour les modèles descendants.
  • Les textures ne sont pas prises en charge ; les mailles imposteur sont rendues comme des mailles lisses.
  • Bien qu'un Model ne soit pas entièrement diffusé, le maillage imposteur est rendu au lieu de parties individuelles du modèlisation.Une fois toutes les parties individuelles diffusées, elles sont rendues et le maillage imposteur est ignoré.
  • Les mailles d'imposteur n'ont aucune signification physique et agissent comme inexistantes en matière de raycasting , de détection de collision et de simulation de physique.
  • L'édition d'un modèle dans Studio, comme l'ajout/suppression/répositionnement de parties enfantes ou la réinitialisation des couleurs, met automatiquement à jour le maillage représentatif.