Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

Cambiar escenas manualmente

A veces es útil tener más control sobre cómo se intercambian las escenas. Como se mencionó anteriormente, los nodos hijos de un Viewport se renderizarán en la imagen que genera, incluso para nodos fuera de la escena "actual". Esto también se aplica a los nodos Autoloads y a las escenas que se instancian y se agregan al árbol en tiempo de ejecución:

var simultaneous_scene = preload("res://levels/level2.tscn").instantiate()

func _add_a_scene_manually():
    # This is like autoloading the scene, only
    # it happens after already loading the main scene.
    get_tree().root.add_child(simultaneous_scene)

Para completar el ciclo y reemplazar la escena nueva con la antigua, los desarrolladores tienen que tomar una decisión. Existen muchas estrategias para eliminar una escena de la vista del Viewport. Los compromisos implican equilibrar la velocidad de operación y el consumo de memoria, así como equilibrar el acceso y la integridad de los datos.

  1. We can delete the existing scene. SceneTree.change_scene_to_file() and SceneTree.change_scene_to_packed() will delete the current scene immediately. Developers can also delete the main scene though. Assuming the root node's name is "Main", one could do get_node("/root/Main").free() to delete the whole scene.

    • Descargas de la memoria.

      • Pro: La RAM ya no arrastra el peso muerto.

      • Con: Volver a esa escena ahora es más costoso, ya que debe cargarse nuevamente en la memoria (toma tiempo y memoria). No es un problema si no es necesario volver pronto a esa escena.

      • Con: Ya no tienes acceso a los datos de esa escena. No es un problema si no necesitas usar esos datos pronto.

      • Nota: Puede ser útil preservar los datos en una escena que pronto será eliminada, volviendo a adjuntar uno o varios de sus nodos a una escena diferente, o incluso directamente al SceneTree.

    • Detención de procesamiento.

      • Pro: Sin nodos, no hay procesamiento, procesamiento de físicas o manejo de entrada. La CPU está disponible para trabajar en el contenido de la nueva escena.

      • Con: El procesamiento y el manejo de entrada de esos nodos ya no operan. No es un problema si no es necesario utilizar los datos actualizados.

  2. Podemos ocultar la escena existente. Al cambiar la visibilidad o la detección de colisiones de los nodos, podemos ocultar todo el subárbol de nodos desde la perspectiva del jugador.

    • La memoria aun existe.

      • Pro: Aún se puede acceder a los datos si es necesario.

      • Pro: Ya no es necesario mover más nodos para guardar datos.

      • Con: Se está manteniendo más datos en la memoria, lo que puede convertirse en un problema en plataformas sensibles a la memoria, como web o dispositivos móviles.

    • Continuación de procesamiento.

      • Pro: Los datos continúan recibiendo actualizaciones de procesamiento, por lo que la escena mantendrá actualizados todos los datos dentro de ella que dependan del tiempo delta o de los datos de fotogramas.

      • Pro: Los nodos siguen siendo miembros de grupos (ya que los grupos pertenecen al SceneTree).

      • Con: La atención de la CPU ahora está dividida entre ambas escenas. Demasiada carga podría resultar en bajos índices de fotogramas (frame rates). Es importante asegurarse de probar el rendimiento a medida que avanzas para asegurar que la plataforma objetivo pueda soportar la carga que le estás dando.

  3. Podemos eliminar la escena existente del árbol. Asigna una variable al nodo raíz de la escena existente. Luego, usa Node.remove_child(Node) para desvincular toda la escena del árbol.

    • La memoria sigue existiendo (pros y contras similares a ocultarla de la vista).

    • El procesamiento se detiene (pros y contras similares a eliminarlo por completo).

    • Pro: Esta variación de "ocultarla" es mucho más fácil de mostrar/ocultar. En lugar de llevar un registro de múltiples cambios en la escena, solo se necesita llamar al par de métodos add/remove_child. Es similar a desactivar objetos de juego en otros motores.

    • Con: A diferencia de ocultarla solo de la vista, los datos contenidos dentro de la escena se volverán obsoletos si dependen del tiempo delta, la entrada, los grupos u otros datos que se derivan del acceso a SceneTree.

También hay casos en los que uno puede desear tener muchas escenas presentes al mismo tiempo. Quizás se esté agregando un singleton propio en tiempo de ejecución o preservando los datos de una escena entre cambios de escena (agregando la escena al nodo raíz).

get_tree().root.add_child(scene)

Perhaps instead they wish to display multiple scenes at the same time using SubViewportContainers. This is optimal in cases where the intent is to render different content in different parts of the screen. Minimaps and split-screen multiplayer are good examples.

Cada opción tendrá casos en los que sea más adecuada, por lo que uno debe examinar los efectos de cada una y determinar qué camino se adapta mejor a su situación única.