Add a counterpart to Initialize, such as Deactivate

geoffd

New member
I found an interesting problem with the DisplayPanel systems.

During Initialize(), I am registering a number of events handlers in some display panels - I use ScriptableObjects for messaging and so these event handlers are registered with those SOs. However, these panels are disabled by default, and so if I destroy the panel manager during scene transitions without having opened those those child panels, I am unable to de-register those event handlers. This is because Unity doesn't call OnDestroy() if an object is never enabled. This means that if I fire those events later, there are references to destroyed objects and Unity craps the bed.

Having a "Deactivate" counterpart to Initialize (which should be fired OnDestory() on the display panel manager I think?) would allow me clean-up those panels between scene transitions, even if they were never enabled. I've handled this with some other custom components at this time, but the approach smells. Please consider my request.

And thank you. Your asset is really awesome. It's worth every penny and helps make my dreams as a hobby solo-dev realizable.
 
I see what you mean...
So from the top level I would call the OnDestroy function (Or maybe a custom Cleanup function just to make sure there is a distinction) on all DisplayPanels within the DisplayPanelManager.

Would that help for your use case? (I'm unsure where and how you are registering your events and how you expect to unregister them. Are you overriding the DisplayPanel class to add your functionalit or Are you using a custom DisplayPanelBinding perhaps?)
 
Thank you for your quick response. Yes, I think a clean-up method would be the most clear.

Apologies though, I should have included more context in my original message; I use events to decouple my GUI from the rest of my game. These events are broadcast through ScriptableObjects; I like this pattern as I just need to drop that SO on a component that wants to broadcast/receive events of a particular context. In the below example, my Crafting menu has a custom DisplayPanelBinding component that receives 3 events. One to open the menu with the default crafter, another to open the menu with a non-default crafter (like if the player interacts with a crafting bench) and another event to close the menu.

I register handlers with these event during Initialize() and I unregsiter in OnDestroy(). The problem is that if the menu is destroyed before being opened, OnDestroy is never called and those event handlers remain registered referencing a destroyed object. OnDestroy is not called for components that are never enabled, so if the player doesn't open the crafting menu and it gets destroyed on a scene transition, and subsequently recreated in a later scene, broadcasting events on those SOs will now cause an exception because of the orphaned event handlers. Hopefully that is clear.

If there was another method like "Cleanup()" on DisplayPanelBinding that is called when the DisplayPanelManager is destroyed, I could override that to do this clean-up.

Thanks again! Please let me know if you need further information.

events.PNG
 

Attachments

  • events.PNG
    events.PNG
    83.6 KB · Views: 1
  • eventchannel.PNG
    eventchannel.PNG
    23.7 KB · Views: 1
Ok that makes perfect sense.
I'll add that in the next update.

Most likely within the OnDestoy method of the DipsplayPanelManager I will call a "UnInitialize" function on all the displayPanels (I think that name might be more clear than "cleanup" or "destroy")

I hope that makes sense.

Feel free to implement this on your side to make sure it works as you expect, so that you don't have to wait for the next update
 
Top