Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only.

    Please, do not make any changes to your username or email addresses at id.unity.com during this transition time.

    It's still possible to reply to existing private message conversations during the migration, but any new replies you post will be missing after the main migration is complete. We'll do our best to migrate these messages in a follow-up step.

    On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live.


    Read our full announcement for more information and let us know if you have any questions.

Question Scene Management

Discussion in 'DOTS Dev Blitz Day 2022 - Q&A' started by JohnnyTurbo, Dec 8, 2022.

  1. JohnnyTurbo

    JohnnyTurbo

    Joined:
    May 17, 2017
    Posts:
    42
    Hello and thanks for taking the time to answer these questions!

    I'd like to learn a bit more about some approaches to scene management. Often times I'll want to have multiple scenes with different combinations of systems running i.e. Scene 1 runs systems A, B, C; Scene 2 runs systems X, Y, Z; Scene 3 runs systems B, X, Q.

    Getting them to update at different times is no problem with RequireForUpdate, but often times I still want to use the other system lifecycle functions for setup, initialization, cleanup, etc.

    Is the best approach typically to just do my own system management for my custom systems (e.g. have a script that creates/destroys systems based off the scene) or should I be thinking about the problem in another way?

    Also, what would be the best way to just do a simple reload on a scene? In the past I've just nuked then recreated the World so all the proper initialization systems run and entities get recreated, but wondering if there is a better way.

    Thank you!
    -Johnny
     
    ildarshara likes this.
  2. jivalenzuela

    jivalenzuela

    Unity Technologies

    Joined:
    Dec 4, 2019
    Posts:
    93
    Howdy JohnnyTurbo!

    I'm assuming systems here are associated with gameplay elements that can have some sort of authoring data placed in the scene? That is
    • Scene 1 has Mushrooms, Platforms, Stars
    • Scene 2 has Turtles, Pipes, Bullets
    • Scene 3 has Platforms, Pipes, Flowers

    Would you mind going into a little more detail about how you intend to use the system lifecycle functions and what uncertainty you're having? I'm not quite sure I'm clear.
     
  3. TheOtherMonarch

    TheOtherMonarch

    Joined:
    Jul 28, 2012
    Posts:
    901
    I am using multiple worlds and only adding the systems I need; in order to separate my graphics and physics.
     
  4. JohnnyTurbo

    JohnnyTurbo

    Joined:
    May 17, 2017
    Posts:
    42
    Thanks for the response @jivalenzuela
    Mostly this would be for things like a generation system that runs when I load a new level or if I have a system that caches a singleton entity at the beginning of a scene so it can have that for the update loop. When launching just a single scene at a time, everything works as intended as all the OnCreate methods get called as do the systems that update once and disable themselves.

    However, if I load into a new scene, those systems could already be running thus the OnCreate wouldn't be called, or systems that disabled themselves would remain disabled. Easy enough to manually recreate or reenable the system, but this could become a bit of a mess as the amount of scenes, systems, and combinations of the two increase.

    Does it make sense to have one world per scene?
     
  5. Jonas_DM_

    Jonas_DM_

    Joined:
    Feb 28, 2019
    Posts:
    22
    Hey Johnny,

    Jonas here :) (from the twitch stream we did together)
    I think (like you alluded) it could make things simpler if you look at the problem through another lens.

    When thinking about systems I find it simplest to think of them as something that would do OnCreate at the start of the game, OnDestroy at the end of the game & OnUpdate on every frame inbetween.
    (this is not always true, but works well as a mental model)

    So when you need to do Initialization on entities you can use components or missing components to query for all entities that need initialization done on them.
    Example: For every entity with X Component, add Y Component & Remove/Disable X Component.
    Example: For every entity without Z Component, add Z Component
    Example: For every entity with Q Component, add Entity to NativeList from MySystem & then remove Q Component.
    There's also a neat trick if you'd like to do something right after each subscene section load: Inside of a BakingSystem you can create an entity, add the correct SceneSection component to it & then add your own Component A to it.
    Then in your game in 'InitSceneSectionSystem' you can just RequireForUpdate Component A & in the Update do anything with Component A or the SceneSection & then disable the entity.


    When you need to do Cleanup on entities you can use ICleanupComponent which allows you to do some cleanup after something destroyed the entity.
    In some cases you might want to do something before the entities from a scene get destroyed. This is quite easy to achieve by adding some custom scene unloading component instead of straight removing the RequestSceneLoaded component from the SceneSection.

    I hope this is relevant or at least a bit useful. Wasn't sure if I actually understood the question 100% hah.

    To answer your second question:
    You can load a scene or scenesection by adding the RequestSceneLoaded to the correct scene or scenesection entity. You can even make these scene entities yourself afaik.
    To unload them you just remove the RequestSceneLoaded from that same entity.
    So to reload a scene you'd remove the component, then check some data (depends on your use case) to see if the scene is unloaded & then add it again afterwards.
    There's also the SceneSystem that you can use, but I prefer working with the componentdata.
     
    JohnnyTurbo and DaxodeUnity like this.
  6. JohnnyTurbo

    JohnnyTurbo

    Joined:
    May 17, 2017
    Posts:
    42
    Hey @Jonas_DM_ great to hear from you and hope you've been doing well!

    Thanks for the suggestion these all seem like good options to play around with. I would definitely like to experiment with the SceneSection as I've never done anything with that yet.

    I know your game used subscenes quite heavily and that there are a lot of powerful things you can do with them, so I'd like to do more than just the basics with them, and these seem like awesome things to test out.

    All the best and hope to see you at GDC again next year ;)
     
    Jonas_DM_ likes this.
  7. Botaurus

    Botaurus

    Joined:
    Feb 20, 2013
    Posts:
    81
    I'm currently trying to wrap my head around scene management in ecs. Figured I'd post here rather than make a new thread. Having two scene management systems is breaking by brain.
    1) how does my spawning system know which subscene to put instantiated entities in? Systems don't seem to be associated with any scene (and from the comments above sounds like I should think of them independent of scenes). I guess its because the prefab was set in an authoring component that lives in the subscene (which seems like only a loose association)
    2) I tried creating an entity from code only, it goes into the top level of the hierarchy, under no subscene. Is there a way to put it in a subscene?
    3) when I want to change scenes using the old scene manager, should I first unload my subscenes and clean up any non-subscene parented entities myself, then run the old scene manager?
    4) since systems are always active - to detect a scene change (using the old scene manager) in ECS, I suppose I'd have a 'newScene' tag component on an entity in a new scene, do something in a system.update once, then remove the component?

    Thank you

    upload_2023-1-17_23-29-56.png
     
  8. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,349
    This then results in the prefab being baked in the subscene as a prefab belonging to the subscene. And consequently, it receives the SceneTag shared component associated with that subscene. Note: "SceneTag" is a misleading name, because the component actually contains data.
    The SceneTag component is one of the requirements. There might be more, but I don't remember. My use case was ensuring the instantiated prefab was kept alive when the subscene unloaded, so I removed the SceneTag.
    Subscenes are managed by Subscene MonoBehaviours. The MonoBehaviour will automatically close the subscne on scene change when it is destroyed. You'll still need to do something about entities that were created procedurally.
    That's one way to do it. I keep what is effectively a singleton and have a scene management system that handles switching scenes and reports scene state to that singleton. It reports the new scene name, the previous scene name, and a bool specifying if this is the first frame of the new scene.
     
    Jonas_DM_ and Botaurus like this.
  9. Jonas_DM_

    Jonas_DM_

    Joined:
    Feb 28, 2019
    Posts:
    22
    Putting a dynamically created entity into a loaded subscene is indeed possible (Like Latios mentioned).
    But it needs both the SceneTag & SceneSection SharedComponents as far as I'm aware.
     
    Botaurus likes this.