Archive 17/01/2023.

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

cirosantilli

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

[link is deleted by Admin]

1vanK

save and load from file?

cirosantilli

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

Eugene

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

1vanK
Save(Serializer& dest)

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

cirosantilli

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

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

1vanK

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

Eugene

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.

cirosantilli

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.

1vanK

Create new scene and delete old…

Modanung

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.

Eugene

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

1vanK

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_);
        }
    }
johnnycable

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

cirosantilli

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.

weitjong

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.

artgolf1000

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

weitjong