En la experiencia , la transmisión de instancias permite al motor de Roblox cargar y descargar dinámicamente contenido 3D e instancias relacionadas en regiones del mundo. Esto puede mejorar la experiencia general del jugador de varias maneras, por ejemplo:
- Tiempos de unirse más rápidos Los jugadores pueden comenzar a jugar en una parte del mundo mientras más del mundo se carga en el fondo.
- Eficiencia de almacenamiento Las experiencias se pueden reproducir en dispositivos con menos almacenamiento, ya que el contenido se transmite de forma dinámica. Los mundos más inmersivos y detallados se pueden reproducir en una gama más amplia de dispositivos.
- Rendimiento mejorado Mejores velocidades de fotogramas y ejecución, ya que el servidor puede gastar menos tiempo y ancho de banda sincronizando cambios entre el mundo y los jugadores en él. Los clientes pasan menos tiempo actualizando instancias que actualmente no son relevantes para el jugador.
- Nivel de detalle Los modelos remotos y el terreno permanecen visibles incluso cuando no se transmiten a los clientes, manteniendo la experiencia optimizada sin sacrificar por completo las imágenes de fondo.
Habilitar transmisión
La transmisión de instancias está habilitada a través de la propiedad StreamingEnabled del objeto Workspace en Studio. Esta propiedad no se puede establecer en un script. La transmisión está habilitada de forma predeterminada para los nuevos lugares creados en Studio.
Una vez habilitado, se recomienda que se adhiera a las siguientes prácticas:
- Debido a que los clientes normalmente no tendrán todo el Workspace disponible localmente, use la herramienta / API adecuada para asegurarse de que las instancias existan antes de intentar acceder a ellas en un LocalScript . Por ejemplo, utilice controles de transmisión por modelo , detecte la transmisión de instancias , o use WaitForChild() en objetos que pueden no existir.
- Minimiza la colocación de contenido 3D fuera de Workspace . El contenido en contenedores como ReplicatedStorage o ReplicatedFirst no es elegible para la transmisión y puede afectar negativamente el tiempo de unión y el uso de almacenamiento.
- Si mueves el personaje de un jugador configurando su CFrame, hazlo desde un lado del servidor Script y usa solicitudes de transmisión para cargar datos más rápidamente en la nueva ubicación del personaje.
- Establece manualmente el ReplicationFocus del jugador solo en situaciones únicas, como en experiencias que no usan un Player.Character. En estos casos, asegúrate de que el enfoque esté cerca del (de los) objeto (s) que controla el jugador para garantizar que el contenido continúe fluyendo alrededor del punto de interacción del jugador.
Comportamiento técnico
Transmitiendo en
De forma predeterminada, cuando un jugador se une a una experiencia con la transmisión de instancias habilitada, las instancias en el Workspace se replican al cliente, excluyendo lo siguiendo:
- Descendientes de las instancias anteriores
- Instancias no replicantes
Luego, durante el juego, el servidor puede transmitir las instancias necesarias al cliente, según sea necesario.
Comportamiento del modelo
Los modelos configurados para un comportamiento no predeterminado como Atomic stream en reglas especiales como se describe en Per-Model Streaming Controls . Sin embargo, los modelos predeterminados (no atómicos) se envían de manera diferente según si ModelStreamingBehavior está configurado como Default ( Legacy ) o Improved .
Cuando ModelStreamingBehavior está establecido en Por Defecto / Legado , el contenedor Model y sus descendientes no espaciales, como Scripts, se replican al cliente cuando el jugador se une. Luego, cuando sea elegible, los BasePart descendientes del aplicación de modeladoentrarán en el flujo.
Transmisión
Durante el juego, un cliente puede transmitir (eliminar de las Workspace ) regiones del jugador y las BaseParts contenidas dentro de ellas, según el comportamiento establecido por StreamOutBehavior . El proceso comienza con las regiones más alejadas del personaje del jugador (o ReplicationFocus) y se acerca según sea necesario. Las regiones dentro del rango StreamingMinRadius nunca se emiten.
Cuando una instancia se reproduce, está vinculada a nil para que cualquier estado Luau existente se reconecte si la instancia se reproduce de nuevo. Como resultado, las señales de eliminación como ChildRemoved o DescendantRemoving disparan a su padre o antepasado , pero la instancia en sí misma no se destruye en el mismo sentido que una llamada Instance:Destroy().
Para anticipar aún más la transmisión, examina estos escenarios:
Escenario | Ejemplo | Comportamiento de streaming |
---|---|---|
Una parte es creada localmente a través de Instance.new() en un LocalScript . | En un juego de "capturar la Indicador/ marca," creas y adjuntas piezas de casco azul a todos los jugadores del equipo azul a través de un LocalScript . | La parte no se replica en el servidor, y está exenta de la transmisión a menos que la hagas descendiente de una parte que existe en el servidor, como una parte dentro del aplicación de modeladode personaje de un jugador. |
Una parte es clonada localmente de ReplicatedStorage a través de Instance:Clone() en un LocalScript . | Un personaje mago lanza un hechizo activando un Tool , sobre el que se clona un objeto que incluye varios efectos especiales de ReplicatedStorage y se guarda en el espacio de trabajo en la posición del asistente. | La parte no se replica en el servidor, y está exenta de transmitir a menos que la hagas descendiente de una parte que existe en el servidor. |
Una parte es reparada de ReplicatedStorage al espacio de trabajo a través de un LocalScript . | Un "sombrero de mago" se almacena en ReplicatedStorage . Cuando un jugador elige jugar en el equipo del mago, el sombrero se mueve a su modelo de personaje a través de un LocalScript . | La parte sigue siendo elegible para la transmisión, ya que provino del servidor y se replicó a ReplicatedStorage . Evita este patrón, ya que causa una desincronización entre el cliente y el servidor, y la parte puede transmitirse; en su lugar, clona la parte. |
Comportamiento del modelo
Si configuras ModelStreamingBehavior como Improved , el motor puede emitir modelos Default (Nonatomic) cuando sean elegibles para emitir, potencialmente liberando almacenamiento en el cliente y reduciendo las instancias que necesitan actualizaciones de propiedades.
Bajo el comportamiento de transmisión de modelo mejorado, la transmisión de modelos predeterminados (modelos no atómicos) se basa en si el modelo es espacial (contiene BasePart descendientes) o no espacial (no contiene BasePart descendientes).
- Un modelo espacial solo fluye completamente cuando su último descendiente BasePart fluye, ya que algunas de las partes espaciales del aplicación de modeladopueden estar cerca del enfoque del jugador / replicación y otras lejos.
- Un modelo no espacial solo se transmite cuando un antepasado se transmite, lo que equivale al comportamiento de transmisión heredado.
Asambleas y Mecanismos
Cuando al menos una parte de una asamblea es elegible para la transmisión, todas las partes de la asamblea también se transmitirán. Sin embargo, una asamblea no transmitirá hacia fuera hasta que todas sus partes sean elegibles para la transmisión. Durante la transmisión, todas las Constraints y Attachments que descienden de BaseParts y atómicas o persistentes Models también se flujo, lo que ayudará a garantizar actualizaciones de física consistentes en los clientes.
Tenga en cuenta que las asambleas con partes ancladas se tratan un poco diferente que las asambleas con solo partes no ancladas:
Composición de montaje | Comportamiento de streaming |
---|---|
Solo partes no ancladas | El montaje entero se envía como una unidad atómica. |
Parte de raíz anclada | Solo las partes, accesorios y restricciones necesarios para enlazar las partes fluidas con la parte raíz se fluyen juntos. |
Retraso de temporización
Puede haber un ligero retraso de ~10 milisegundos entre cuando se crea una parte en el servidor y cuando se replica a los clientes. En cada uno de los siguientes escenarios, es posible que deba usar WaitForChild() y otras técnicas en lugar de asumir que los eventos y las actualizaciones de propiedades siempre ocurren al mismo tiempo que la transmisión de la parte.
Escenario | Ejemplo | Comportamiento de streaming |
---|---|---|
Un LocalScript hace una RemoteFunction llamada al servidor para crear una parte. | Un jugador activa un Tool localmente para generar una parte en el servidor que todos los jugadores puedan ver e interactuar. | Cuando la función remota regrese al cliente, es posible que la parte aún no exista, aunque la parte esté cerca del enfoque del cliente y dentro de un área transmitida. |
Una parte se añade a un modelo de personaje en el servidor a través de un Script y un RemoteEvent se dispara a un cliente. | Cuando un jugador se une al equipo de policía, una parte de "insignia de policía" almacenada en ServerStorage se clona y se adjunta al aplicación de modeladode personaje del jugador. Un RemoteEvent es disparado y recibido por el cliente de ese jugador para actualizar un elemento de interfaz de usuario local. | Aunque el cliente reciba la señal del evento, no hay garantía de que la parte ya se haya transmitido a ese cliente. |
Una parte colisiona con una región invisible en el servidor y activa un RemoteEvent en el cliente. | Un jugador lanza un balón de fútbol a una portería, lo que desencadena un evento de "gol marcado." | Otros jugadores que están cerca de la portería pueden ver el evento "gol marcado" antes de que el balón se les haya transmitido. |
Propiedades de streaming
Las siguientes propiedades controlan cómo se aplica el streaming de instancias a tu experiencia. Todas estas propiedades son no programables y deben configurarse en el objeto Workspace en Studio.
Comportamiento de transmisión de modelos
Controla si los modelos Por Defecto (No Atómicos) se replican cuando un jugador se une, o solo se envían cuando sea necesario. Si esta propiedad está configurada como Mejorado , los modelos en Workspace solo se enviarán a los clientes cuando sea necesario, lo que potencialmente acelerará los tiempos de adhesión. Consulte Comportamiento Técnico para más detalles.
Modo de integridad de transmisión
Tu experiencia puede comportarse de formas no deseadas si un jugador se mueve a una región del mundo que no se le ha transmitido. La función integridad de transmisión ofrece una manera de evitar esas situaciones potencialmente problemáticas. Consulte la documentación Enum.StreamingIntegrityMode para más detalles.
StreamingMinRadius
La propiedad StreamingMinRadius indica el radio alrededor del personaje del jugador (o ReplicationFocus ) en el que las instancias se transmitan con la mayor prioridad. Se debe tener cuidado al aumentar el valor predeterminado, ya que al hacerlo requerirá más almacenamiento y más ancho de banda del servidor a expensas de otros componentes.
Radio de objetivo de transmisión
La propiedad StreamingTargetRadius regula la distancia máxima del personaje del jugador (o ReplicationFocus ) en el que se transmiten las instancias. Tenga en cuenta que el motor puede retener las instancias cargadas anteriormente más allá del radio del objetivo, lo que permita la memoria.
Un StreamingTargetRadius más pequeño reduce la carga de trabajo del servidor, ya que el servidor no transmitirá en instancias adicionales más allá del valor establecido. Sin embargo, el radio de objetivo también es la distancia máxima a la que los jugadores podrán ver el detalle completo de su experiencia, por lo que debe elegir un valor que cree un buen equilibrio entre estos.
Comportamiento de StreamOut
La propiedad StreamOutBehavior establece el streaming out comportamiento según uno de los siguientes valores:
Ajustes | Comportamiento de streaming |
---|---|
Por defecto | Comportamiento predeterminado, actualmente el mismo que LowMemory . |
Baja Memoria | El cliente solo transmite partes en una situación de bajo almacenamiento y puede eliminar contenido 3D hasta que solo esté presente el radio mínimo. |
Oportunista | Las regiones más allá de StreamingTargetRadius se pueden eliminar en el cliente incluso cuando no hay presión de almacenamiento. En este modo, el cliente nunca elimina las instancias que están más cerca que el radio de destino, excepto en situaciones de bajo almacenamiento. |
Controles de streaming por modelo
A nivel mundial, la propiedad ModelStreamingBehavior le permite controlar cómo se transmiten los modelos al unirse. Además, para evitar problemas con la transmisión por modelo y minimizar el uso de WaitForChild(), puede personalizar cómo Models y sus descendientes transmiten a través de su propiedad ModelStreamingMode.
Por defecto / No Atómico
Cuando un Model está configurado como Por Defecto o No Atómico , el comportamiento de transmisión varía según si ModelStreamingBehavior está configurado como Por Defecto ( Legacy ) o Mejorado .
Comportamiento de transmisión de modelos | Comportamiento técnico |
---|---|
Por Defecto ( Legado ) | El modelo se replica cuando un jugador se une. Esto potencialmente da como resultado más instancias enviadas durante la carga, más instancias almacenadas en el almacenamiento y complejidad adicional para los scripts que quieren acceder a los descendientes del aplicación de modelado. Por ejemplo, un LocalScript separado necesitará usar WaitForChild() en un descendiente BasePart dentro del aplicación de modelado. |
Mejorado | El modelo solo se envía cuando es necesario, lo que potencialmente acelera los tiempos de unirse. |
Véase Comportamiento Técnico para más detalles.
Atómico
Si un Model se cambia a Atomic , todos sus descendientes se transmitirán juntos cuando un descendiente BasePart sea elegible. Como resultado, un LocalScript separado que necesita acceder a instancias en el modelo necesitaría usar WaitForChild() en el modelo en sí, pero no en un descendiente MeshPart o Part ya que se envían junto al aplicación de modelado.
Un modelo atómico solo se transmite cuando todas sus partes descendientes son elegibles para transmitirse, momento en el que todo el modelo se transmite juntos. Si solo se transmitieran algunas partes de un modelo atómico, todo el modelo y sus descendientes permanecen en el cliente.
Script local
-- El modelo atómico no existe en el momento de la carga; use WaitForChild ()local model = workspace:WaitForChild("Model")-- Las partes descendientes fluyen con el modelo y son inmediatamente accesibleslocal meshPart = model.MeshPartlocal part = model.Part
Persistente
Los modelos persistentes no están sujetos a la transmisión normal. Se envían como una unidad atómica completa poco después de que el jugador se una y antes de que el Workspace.PersistentLoaded evento se dispare. Los modelos persistentes y sus descendientes nunca se transmiten, pero para manejar de manera segura la transmisión dentro de un LocalScript separado, debe usar WaitForChild() en el aplicación de modeladopadre o esperar a que se desencadenarel PersistentLoaded evento.
Script local
-- El modelo persistente no existe en el momento de la carga; use WaitForChild ()local model = workspace:WaitForChild("Model")-- Las partes descendientes fluyen con el modelo y son inmediatamente accesibleslocal meshPart = model.MeshPartlocal part = model.Part
PersistentePorJugador
Los modelos configurados como PersistentePerPlayer se comportan igual que Persistente para los jugadores que se han agregado usando Model:AddPersistentPlayer() . Para otros jugadores, el comportamiento es el mismo que Atomic . Puede revertir un modelo de la persistencia del jugador a través de Model:RemovePersistentPlayer() .
Solicitando Streaming de Área
Si estableces el CFrame de un personaje de jugador en una región que no está cargada actualmente, se produce una pausa de transmisión, si está habilitada. Si sabe que el personaje se moverá a una área específica, puede llamar a Player:RequestStreamAroundAsync() para solicitar que el servidor envíe regiones alrededor de esa ubicación al cliente.
Los siguientes scripts muestran cómo disparar un evento remoto de cliente a servidor para teletransportar a un jugador dentro de un lugar, rindiéndose a la solicitud de transmisión antes de mover el personaje a un nuevo CFrame .
Script - Teletransportar personaje del jugador
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local teleportEvent = ReplicatedStorage:WaitForChild("TeleportEvent")
local function teleportPlayer(player, teleportTarget)
-- Solicitar streaming alrededor de la ubicación objetivo
player:RequestStreamAroundAsync(teleportTarget)
-- Teletransportar personaje
local character = player.Character
if character and character.Parent then
local currentPivot = character:GetPivot()
character:PivotTo(currentPivot * CFrame.new(teleportTarget))
end
end
-- Llamar a la función de teletransporte cuando el cliente dispara el evento remoto
teleportEvent.OnServerEvent:Connect(teleportPlayer)
LocalScript - Evento Remoto de Fuego
local ReplicatedStorage = game:GetService("ReplicatedStorage")local teleportEvent = ReplicatedStorage:WaitForChild("TeleportEvent")local teleportTarget = Vector3.new(50, 2, 120)-- Dispara el evento remototeleportEvent:FireServer(teleportTarget)
Detectando transmisión de instancias
En algunos casos, es necesario detectar cuando un objeto entra o sale y reaccionar a ese evento. Un patrón útil para la detección de transmisión es el siguiente:
Usando las Etiquetas sección de las propiedades de una instancia, o el Editor de Etiquetas de Studio, asigna una lógica CollectionService etiqueta a todos los objetos afectados.
Desde un solo LocalScript, detecte cuándo un objeto etiquetado ingresa o sale a través de GetInstanceAddedSignal() y GetInstanceRemovedSignal(), luego maneje el objeto en consecuencia. Por ejemplo, el siguiente código agrega objetos etiquetados Light a un bucle "parpadeando" cuando ingresan y los elimina cuando salen.
LocalScript - Detección de streaming de CollectionServicelocal CollectionService = game:GetService("CollectionService")local tagName = "FlickerLightSource"local random = Random.new()local flickerSources = {}-- Detecta las partes etiquetadas actuales y nuevas que entran o salenfor _, light in CollectionService:GetTagged(tagName) doflickerSources[light] = trueendCollectionService:GetInstanceAddedSignal(tagName):Connect(function(light)flickerSources[light] = trueend)CollectionService:GetInstanceRemovedSignal(tagName):Connect(function(light)flickerSources[light] = nilend)-- Ciclo de parpadeowhile true dofor light in flickerSources dolight.Brightness = 8 + random:NextNumber(-0.4, 0.4)endtask.wait(0.05)end
Personalización de la pantalla de pausa
La propiedad Player.GameplayPaused indica el estado de pausa actual del jugador. Esta propiedad se puede usar con una conexión GetPropertyChangedSignal() para mostrar u ocultar una Interfaz gráfica (o GUI)personalizada.
Script local
local Players = game:GetService("Players")
local GuiService = game:GetService("GuiService")
local player = Players.LocalPlayer
-- Desactivar modo de pausa predeterminado
GuiService:SetGameplayPausedNotificationEnabled(false)
local function onPauseStateChanged()
if player.GameplayPaused then
-- Mostrar Interfaz gráfica (o GUI)personalizada
else
-- Ocultar Interfaz gráfica (o GUI)personalizada
end
end
player:GetPropertyChangedSignal("GameplayPaused"):Connect(onPauseStateChanged)
Nivel de detalle del modelo
Cuando la transmisión está habilitada, Models fuera del área actualmente transmitida no será visible por defecto. Sin embargo, puede instruir al motor para renderizar mallas "imposter" de menor resolución para modelos que no están presentes en clientes a través de la propiedad LevelOfDetail de cada aplicación de modelado.
Configuración del modelo | Comportamiento de streaming |
---|---|
StreamingMesh | Activa la generación asíncrona de una malla de impostor para mostrar cuando el modelo no esté presente en los clientes. |
Deshabilitado / Automático | El modelo desaparece cuando está fuera del radio de transmisión. |
Cuando uses redes impostoras, ten en cuenta lo siguiendo:
- Las mallas impostoras están diseñadas para ser vistas a 1024 studs de distancia de la cámara o más lejos. Si has reducido StreamingTargetRadius a un valor mucho más pequeño, como 256, es posible que las mallas impostoras no sean visualmente aceptables para el modelo que reemplazan.
- Si un modelo y sus modelos descendientes están configurados en StreamingMesh , solo el modelo antepasado de nivel superior se renderiza como una malla impostora, envolviendo todas las geometrías bajo el antepasado, así como sus modelos descendientes. Para un mejor ejecución, se recomienda usar Deshabilitado para los modelos descendientes.
- Las texturas no son compatibles; las mallas impostoras se renderizan como mallas lisas.
- Si bien un Model no se reproduce completamente, la malla impostora se renderiza en lugar de las partes individuales del aplicación de modelado. Una vez que todas las partes individuales se reproducen, se renderizan y se ignora la malla impostora.
- Las mallas impostoras no tienen significado físico y actúan como inexistentes con respecto a Raycasting, detección de colisiones y simulación de física.
- Al editar un modelo en Studio, como agregar/eliminar/reposicionar partes menores o restablecer colores, se actualiza automáticamente la malla representativa.