Search Unity

How to subscribe to Application Pause event from a non-MonoBehaviour script?

Discussion in 'Scripting' started by ChristopherCreates, Apr 28, 2016.

  1. ChristopherCreates

    ChristopherCreates

    Joined:
    Apr 8, 2015
    Posts:
    24
    I have a non-MonoBehaviour script and I need to have it fire a method when the application gets paused or un-paused. Is there a way to get OnApplicationPause functionality outside of a MonoBehaviour? This is for an asset, so making a separate MonoBehaviour to call it would be a bit clunky.

    Thanks!
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,532
    Is there a reason this class is not a MonoBehaviour yet needs to react like this? Why can't it be signaled to when that event happens.

    What I mean is that this class is not a MonoBehaviour, so thusly it can't be attached to a GameObject. This means it's most likely instantiated within some MonoBehaviour some where, there's very few ways it could ever be instantiated otherwise. So where it gets instantiated would have access to that event, so can't that signal this class when that event occurs?

    Otherwise you're going to have to set up a static/global event for it. This can be done with a singleton that inherits MonoBehaviour that has the message in it, and that singleton raises an event when it occurs. Because it's a singleton this class can access it globally, and register for the event.

    Although, the need for this suggests to me that your class may be ill-designed. What is this for exactly?
     
  3. ChristopherCreates

    ChristopherCreates

    Joined:
    Apr 8, 2015
    Posts:
    24
    It's a static class managing native Android functionality (AndroidJavaObject, etc), so it wouldn't make sense for it to be a MonoBehaviour. I tried making a class that inherits from MonoBehaviour just to handle this part, but it didn't receive the OnApplicationPause event. I assumed that was because it wasn't attached to a GameObject. Is there a way to subclass it that will work?

    Thanks!
     
  4. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,532
    MonoBehaviours can ONLY be attached to GameObjects. So if you say it didn't receive the OnApplicationPause when you inherited from MonoBehaviour, I suspect you kept it as a static class... static members don't receive those messages.

    You can make it a Singleton instead, then it'd receive that message just fine. Just make it not destroy on load.
     
  5. ChristopherCreates

    ChristopherCreates

    Joined:
    Apr 8, 2015
    Posts:
    24
    Well, my point is that I want a way to get the event without involving a GameObject. This functionality isn't related to any particular GO, so asking my users to add another component to their scene just to get this event seems like a needless extra step. The application knows when it gets paused and unpaused outside of any GOs, so I'm just looking for a way to tap into that.

    I'm looking at connecting into the native Android app events, but that seems like overkill. Surely Unity has a simple way to subscribe to system events outside of MonoBehaviours?
     
    IARI likes this.
  6. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,532
    This event is only dispatched to GameObjects, so there will have to be a GameObject somewhere.

    Why would your users have to add it to their scene? You add it when the game starts, and make it never destroy. It'll exist perpetually in the background.
     
  7. Grinay

    Grinay

    Joined:
    Jul 6, 2013
    Posts:
    27
    You must have least one GameObject for do that.
    For example you need to create GameObject with script who has singleton pattern, And there you need to create delegate and event for subscribe.
    Then you can fire your custom event in onapplicationpause event. I don't know another way to do that
     
  8. ChristopherCreates

    ChristopherCreates

    Joined:
    Apr 8, 2015
    Posts:
    24
    I may just have the static constructor automatically generate a GameObject and put a MonoBehaviour on it that will catch the events. It's still clunky, but it would be less clunky than asking the user to do it.
     
  9. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,532
    careful with doing that in a static constructor.

    Gameobjects can only be created on the main thread. If that static constructor happens to get called not on the main thread, it'll throw an error.

    I honestly don't know why you demand this be a static class and that it "doesn't make sense" to be a monobehaviour. A monobehaviour singleton would give you exactly what you need.
     
  10. ChristopherCreates

    ChristopherCreates

    Joined:
    Apr 8, 2015
    Posts:
    24
    Thanks for the tip! And the other feedback. :)