[SOLVED] TypeError (Cannot read property 'enabled' of null) after returning to scene

Hello, I’ve been stuck on this problem for a couple of days and maybe you can help me out…

I’ve forked my private project into a public project and stripped everything that wasn’t needed to replicate the bug.
You can find the project here: https://playcanvas.com/project/705604

The problem is within my Inventory system.
To reproduce the bug follow the following steps starting from the InitialScene:

  1. click on “play”
  2. click on the red square (that will fill the inventory)
  3. click on the arrow pointing to east (that will change scene)
  4. click on the arrow pointing to west (that will take you back to the previous scene)
  5. click on the inventory button (that will open the inventory, of course)

The error is:
Uncaught TypeError (Cannot read property ‘enabled’ of null)
at ElementComponent.get (playcanvas-stable.dbg.js:28112), it seems to be related to the update of the hierarchy when the parent panel entity is enabled
the issue happens when there are items in the inventory, so it must be some element component of the items icons that is expected to have the enabled property, I guess…

If you open the inventory before you return to that scene, it doesn’t happen.

Technically this is what I’m trying to do:

The Inventory is a script added to an Entity which in turn is a child of a Screen Entity that embeds the UI.

Most of the entities in the initialScene are meant to be carried around for the whole game, so I’ve renamed the root entity to PersistenRoot. When I change scene the first time (pushing the “play” button) only part of the entities are destroyed.
From that point on, changing scene (clicking on the yellow arrows) will destroy the Root entity of the actual scene (always mantaining the PersistentRoot).

Each scene has an entity with a SceneManager script (that works as a singleton registering itself when the scene is loaded, overwriting the previous SceneManager instance).

Items will be scattered through the games, each scene will contain the items that can be found there as child of the SceneItems entity.
Each item has an ItemIcon script that on initialize will check if the Inventory contains a copy of that item (using a string key). If the inventory contains the key, the ItemIcon will self destruct (the name of the entity destroyed is printed on the console, to keep track of this).
Otherwise it will register itself to the SceneManager’s item icons list (so it can be easily found by other scripts).

When the player obtains an item, that item’s key is searched in the Inventory (if it’s found there, only the quantity held by the player is changed), or in the SceneManager (in this case, the ItemIcon is reparented to the Inventory layout entity and added in the Inventory list).
When it’s reparented, its name is changed by appending “(in inventory)” to it.

Whenever the Inventory is opened, all children of the layout are printed in the console, so I know that they (and their element component) are not null.

Do you have any tips on how to tackle this problem?

Welcome to the forums!

Well, are you certain this is the smallest possible example you can create to reproduce the problem? :slight_smile: There is a lot happening. If the issue is with retaining a variable from a scene to a scene, perhaps you could create two scenes and show how you save and access that variable/item? It doesn’t need to be pretty or be fully featured, but it should preferrably have a minimum code that shows the problem.

Thank you for your reply!

I’m not sure I can simplify it anymore while mantaining this system, but I’ll try (with a new branch). :confused:

I think you don’t need this system, like adding items through UI, etc. You can create a scene with one entity (item?), simply hardcode it. Then add another scene and ability to return to the first scene? Not sure about your app flow.

Your current error comes from the fact that you are using a reference to an entity to access that entity after it was destroyed on scene change. To solve it, you want to make sure you are saving them in a graph node that is not destoyed upon the scene change.

Also, consider if you need a separate scene, as entities can be arranged in a hierarchy of levels and the parents can be simply enabled/disaabled. If your scenes are not large, then a single scene is enough in most cases.

1 Like

Also, check @yaustar responses in this thread. I think those should be relevant to your case.

Thank you LeXXik for pointing me to that thread, the problem was indeed tied to the GUIDs colliding.

The reference and the graphnode they were reparented to were still intact after changing scene (otherwise the error would set off in the second scene, before returning to the first one).

I’ve changed a couple of line, now the entities are being cloned and all works just fine! :smile:

About the scenes, the game will have 27 levels and even if they are pretty simple, I’d rather avoid having all the entities in memory all the time.
The only issue I had with multiple scenes was this one, if anything else will pop up I’ll consider switching to a single scene!

Thank you again!

1 Like