Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Listeners not being unbound after scene change #12

Closed
DanielPhk opened this issue Mar 1, 2019 · 3 comments
Closed

Listeners not being unbound after scene change #12

DanielPhk opened this issue Mar 1, 2019 · 3 comments

Comments

@DanielPhk
Copy link

Basically I have a few scenes that are almost identical. I use a SmartFloat to get the value from a Slider, directly on the OnValueChange of the Slider. After I switch scenes the script(which is present in both scenes) that references the SmartFloat works as expected but I get a null reference from that same script (which has been destroyed because of the switch to another scene). Note that I didn't bind a listener to it, just accessing the value.

So because everything is working as expected on scene switch, it leads me to believe that there's still a listener bound to the script that has been destroyed on the previous scene...

I know I could write a custom script to bind the listenter to the SmartFloat's update and unbind it on destroy instead of accessing it's value directly, but it seems a listener is persisting from the last scene even though I am just accessing it by value.

@SixWays
Copy link
Collaborator

SixWays commented Mar 5, 2019

Hi, could you post some script and/or screens of your scene setup? A little hard to tell what exactly your code is doing here.

@DanielPhk
Copy link
Author

Hi,

Sorry for the long wait, was really busy ;)

I've attached a repro project.

Simple instructions to reproduce on the README file.

Thanks!

SmartDataBug.zip

@sigtrapgames
Copy link
Owner

Sorry on my end too - only just got around to this! So there's a couple of things - there IS a bug here, but it's not what you're thinking.

UnbindOnDestroy doesn't unbind all calls to BindListener - that's up to you to manually unbind (cache the returned IRelayBinding and call Enable(false) at end-of-life). What it actually does is unbinds the UnityEvent attached to the SmartRef. So it's expected behaviour that you'll get a nullref in the following scene if you haven't manually unbound your listener. That said - I think I'll change the name to UnbindUnityEventOnDestroy or something to make that clearer since at the moment it does read like you've read it! So apologies for that.

It has uncovered a bug though - turns out, calling UnbindOnDestroy within the first two frames doesn't actually do anything! At least, not in editor - it works fine in builds. UnbindOnDestroy checks whether you're in play mode - if not it ignores it. Which would be fine except the reason for that it to avoid SmartRefs from trying to do stuff during OnAfterDeserialized, which Unity disallows. So it can't actually check Application.isPlaying (again, disallowed during deserialization), and has to rely on subscribing to EditorApplication.playModeStateChanged. Which - drum roll please - it turns out gets called AFTER TWO WHOLE FRAMES OF BEING IN PLAY MODE. Thanks Unity.

So, tl;dr I have to do that slightly differently now!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants