How to reset / restart a Urho3D application scene to its initial state?

http s://stackoverflow.com/questions/47729172/how-to-reset-restart-a-urho3d-application-to-its-initial-state

[link is deleted by Admin]

save and load from file?

Thanks, any way to do it without writing to files? Feels unnecessary.

Well, don’t save and then just load from file. Or save into XMLFile if you need saving.

Save(Serializer& dest)

possible serializer can be memory buffer, but at once I do not remember how

OK, I see virtual bool Save(Serializer& dest) const override;, thanks.

Any way that avoids serialization altogether? That would be most elegant.

I think you can not just memcpy scene, since it contains many pointers to other objects

There is no deep copy of the Scene. Actually, such copying brings more problems than benefits because Scene isn’t an inert object. It is living on its own. So keeping Scene somewhere just to resore from it later may lead to side effects.

I feel copying could be avoided in theory since this is the initial state, which I’m setting up step by step in Start().

But I tried naively to call Start() and it does not work because the UI becomes repeated.

Create new scene and delete old…

How about Scene::Clear()? This removes all Components and Nodes from a scene.

As @weitjong said later: You could call GetSubsystem<UI>()->GetRoot()->RemoveAllChildren() to clear the UI.

1 Like

If you want to naively call Start, you should ensure that you reset everything you initialized during previous Start call. Should work.

Just remember that recreating/switch of scene should be doing before the handling of any events.

class Game : public Application
{
    URHO3D_OBJECT(Game, Application);

public:
    Game(Context* context) : Application(context)
    {
        SubscribeToEvent(E_BEGINFRAME, URHO3D_HANDLER(Game, ApplyGameState));
 void ApplyGameState(StringHash eventType, VariantMap& eventData)
    {
        if (GLOBAL->gameState_ != GLOBAL->neededGameState_)
        {
             GLOBAL->gameState_ = GLOBAL->neededGameState_;
             DoSomething();
        }

        if (GLOBAL->currentLevelIndex_ != GLOBAL->neededLevelIndex_)
        {
            GLOBAL->currentLevelIndex_ = GLOBAL->neededLevelIndex_;
            StartLevel(GLOBAL->currentLevelIndex_);
        }
    }

You have to manage changing scene and its data by application-dependent specific class or data store.
Uhro can manage your scene graphically, but if you need to restart over a level you have to use a level manager

Thanks, I was kind of hoping that there would be a Clear() like method for the whole application (in particular, the UI does not get reset with Scene->Clear, but this solution is acceptable to me.

The UI (and usually also the Camera) is not part of the Scene, so calling scene’s clear would not clear the UI (and camera). You can clear the UI by removing all the children of the root UI element. Assuming “ui” is your UI subsystem singleton object then calling ui->GetRoot()->RemoveAllChildren() should work.

I had written a level manager: Levels Fade Effect, which can switch levels dynamically.