Search Unity

Returning to app in multitasking

Discussion in 'iOS and tvOS' started by Moonjump, Sep 21, 2010.

  1. Moonjump

    Moonjump

    Joined:
    Apr 15, 2010
    Posts:
    2,572
    I've been doing lots of my testing recently on my iPhone 3G running 3.1.3 to check for performance. So I'm not sure at what point the following behaviour changed.

    Last time I checked, my iPhone 4 running Unity 3 would start from the Unity loading screen when reopening the game. Now it returns to the game at the point I left it, which is a problem if that happens to be into a lot of action.

    How do I detect if the game has just regained multitasking focus?
     
  2. Moonjump

    Moonjump

    Joined:
    Apr 15, 2010
    Posts:
    2,572
    My problems have expanded since before.

    If I press the home button while a new player craft is generating, then return to the game, sometimes a second player craft starts generating. This has not occurred under any other circumstances. It is as if the game is restarting a few frames back from the point I exited, causing some actions to happen twice when they shouldn't be.

    Any suggestions?
     
  3. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    The simulation likely restarts at the beginning of the frame.

    What you optimally would do is react to the OnApplicationPause(bool pause) event handler to prevent the dublicate generation etc
     
  4. Moonjump

    Moonjump

    Joined:
    Apr 15, 2010
    Posts:
    2,572
    What can I do as a reaction to the OnApplicationPause?

    I tried;

    Code (csharp):
    1. function OnApplicationPause () {
    2.     Time.timeScale = 0.0;
    3.     Instantiate (pauseMenu);
    4. }
    but that created even bigger problems. It was nice coming back to a paused game, but there were sometimes an extra set of enemies created, totally messing up the game logic.

    I have tried adding UIApplicationExitsOnSuspend to the Info.plist in Xcode, but Unity overwrites it each time I do a build, even though I use Append. That would be the quick solution, but how do I get it to stick?

    On one occasion UIApplicationExitsOnSuspend still appeared to be there, but it didn't make any difference, and disappeared when I looked after quitting Tasks in Xcode.
     
  5. Moonjump

    Moonjump

    Joined:
    Apr 15, 2010
    Posts:
    2,572
    I've been doing a lot more testing of this today. Here is what I have discovered:

    The game often doesn't stop immediately. I have heard my player die after the screen went blank when switching away from the game. The player is dead upon returning.

    If I use the function OnApplicationPause () I previously mentioned, when I return to the game, the game plays briefly, then goes into the pause state. I use the same play button on my main and pause menus. The action is produces is based on detecting the Time.timescale, 1.0 for main menu, 0.0 for the pause menu. Although a game is paused on return from app switching, and the Time.timescale looks to be o.o, It is triggering the action as if Time.timescale was 1.

    So my problems stem from the app not stopping and starting cleanly. I cannot see a way around this.

    Any help welcome as this bug, Game Center integration, and more testing are the only things required for release.

    EDIT: I will change to 2 separate Play buttons, but wanted to highlight the wrong setting of Time.timescale.
     
  6. Moonjump

    Moonjump

    Joined:
    Apr 15, 2010
    Posts:
    2,572
    Is it possible to detect the actual Home button press and use that as the trigger for the game to set pause? That may solve my problem.
     
  7. mudloop

    mudloop

    Joined:
    May 3, 2009
    Posts:
    1,107
    Don't think so, there's always a slight delay (which happens during the fade out effect).
     
  8. Moonjump

    Moonjump

    Joined:
    Apr 15, 2010
    Posts:
    2,572
    Thanks Smag,

    The more I look at it, the more problems I discover.

    If I return to the game on the main menu, the music isn't playing. That music comes from on Audio Source on one of the menu objects. It is set to play on awake and loop.
     
  9. mudloop

    mudloop

    Joined:
    May 3, 2009
    Posts:
    1,107
    Yeah, I saw that too. I just restart it when the game wakes up.

    You can have OnApplicationPause with a bool parameter which tells you whether the game is pausing or waking up.
     
  10. Moonjump

    Moonjump

    Joined:
    Apr 15, 2010
    Posts:
    2,572
    I've spent the last couple of days tearing my hair out. I cannot find a way to stop the game running at the point the home button is pressed. It is causing bugs, but even if it were not, it is still a big problem. A player can press the home button to exit the game, and come back to find the game in a different situation, possibly with a life lost.

    I have therefore put a feature request in for a way to detect when the home button is detected. Hopefully something like:

    Code (csharp):
    1. if (Input.GetButtonDown ("Home"))
    Here is the request if anyone would also like the feature:

    http://feedback.unity3d.com/forums/...ns/1084259-iphone-home-button-press-detection
     
  11. mudloop

    mudloop

    Joined:
    May 3, 2009
    Posts:
    1,107
    I don't think they can. I think it's iOS thing. Not entirely sure though.
     
  12. Moonjump

    Moonjump

    Joined:
    Apr 15, 2010
    Posts:
    2,572
    From all that I have read it sounds like the game is being paused on a applicationDidEnterBackground rather than a applicationWillResignActive, although I may be totally wrong as I am a bit out of my depth. And I don't know anything about writing Unity iPhone plugins to do a quick test to see if it makes any difference.
     
  13. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    when home is pressed, OnApplicationPause( bool pause ) will be called with pause = true
    when it is unpaused the same function is caused with pause = false.


    it does not make a difference what caused the pause:
    - went into background due to home
    - received a phone call
    - received a notification

    that the stuff is handled in willresignactive etc is fine and correct, because enterbackground would be wrong, enter background / foreground don't allow you to store and process anything anymore, they are "immediate". Its resign where you are always meant to serialize the state for later replication.

    and no you can't hook up home, such stuff is not possible. apple ensured that the iphone unlike the android has a consistent behavior everywhere. You get callbacks called, thats it. no access to any of the hardware buttons without using private api ie never going to happen on the store
     
  14. Moonjump

    Moonjump

    Joined:
    Apr 15, 2010
    Posts:
    2,572
    Could you tell me the correct format for calling the OnApplicationPause when true? Because it certainly isn't happening for me at the time the home button is pressed.

    EDIT:
    This is the way I'm doing it (I haven't had to pass a value in any of my other functions, which is why I am unsure)

    Code (csharp):
    1. function OnApplicationPause (pauseState : boolean) {
    2.     if (gameActive == "play"  pauseState) {
    3.         Time.timeScale = 0.0;
    4.       Instantiate (pauseMenu);
    5.     }
    6. }
     
  15. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    Are you on iOS 4 and at least a 3GS device?
    Otherwise there is no fast appswitch and the application will just be terminated upon pressing home in which case OnApplicationQuit will trigger
     
  16. Moonjump

    Moonjump

    Joined:
    Apr 15, 2010
    Posts:
    2,572
    As mentioned in my first post. The problem is on an iPhone 4 running iOS 4.

    Everything is fine on my iPhone 3G running 3.1.3. There the app quits. when I come back to the game I have it on pause, set to start at the last level before quitting. EDIT: Because it quits immediately with no multitasking, I can rely on the last save point as a place to return to.

    The problem is on my iPhone 4, it is taking several seconds for the game to stop from when I press the home button. I sometimes even hear my player craft get hit after the screen has gone blank.

    Are you saying my code should work?

    EDIT: The game is not actually pausing until just after I return to the game. I am not getting any pause state during the app switching away change.
     
  17. Moonjump

    Moonjump

    Joined:
    Apr 15, 2010
    Posts:
    2,572
    Not that I really expected it to, but Unity 3f3 does not solve the problem.
     
  18. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    OnApplicationPause will be called before it goes to sleep.

    What you can not do there is naturally use a function that will not be executed until the end of the frame as that means it will be executed when you come back (the "next frame").

    So its a matter of what you do.
    time scale setting for example isn't a problem.

    What surely is no problem too is setting the state to "load last savestate" cause the function you call from the main menu can also be called there. Problem is that the users wouldn't want it.

    And if you can't find a way around it or are not fine with the options, you can always modify the info plist file and add the key that tells iOS to terminate the application when it would go into background. Thats what we used on a project I worked on july - aug, because the way the application worked and was meant to work with fetching the current dataset of an expo on startup and cache it, we decided that this is simplest, also in relation to the memory anomalies in relation to dynamically loaded textures which hit us and required many tricks and optimizations.
     
  19. Moonjump

    Moonjump

    Joined:
    Apr 15, 2010
    Posts:
    2,572
    Thanks dreamora,

    I've already tested the UIApplicationExitsOnSuspend option as a backup.

    But not having the option to stop the game immediately on the Home button press (either triggered by the event itself, or triggered by an event triggered by it) seems a very odd situation, particularly on a platform that is so popular for games.

    I cannot believe other people have not run into the same situation, particularly Unity users because many are making fast paced 3D games.

    And I cannot even use the last saved state when multitasking because the state save is sometimes triggered during the period between pressing the home button and the game suspending.
     
  20. jtbentley

    jtbentley

    Joined:
    Jun 30, 2009
    Posts:
    1,397
    So, let me clarify what you've learned (just in case I've mis-read.. its early).

    1. The 'save state' that the device stores appears to be a snapshot of Unity a few seconds before the home button was pressed.
    2. Because of this, you're getting all sorts of behavioral problems
    3. Saving data in the OnWilLResignActive (or like-minded functions) isn't working because of problem #1?
     
  21. Moonjump

    Moonjump

    Joined:
    Apr 15, 2010
    Posts:
    2,572
    1. When returning to the game. The game appears as if running to the last moment before closing, but the data appears to have been saved at an earlier point, possibly from the moment the Home button has been pressed.
    2. Yes, many different problems such as a new player craft generating during the closing down period, then it generating another when restarting. I have put in extra checks that have failed to stop the problems. For example, when generating a player craft, there is an extra check for objects with the tag belonging to the craft.
    3. The code I have tried (repeated below) is an attempt to pause the game at the moment the Home button is pressed, but only does so a moment after returning to the game. I'm am not certain this code is correct.

    Code (csharp):
    1. function OnApplicationPause (pauseState : boolean) {
    2.     if (gameActive == "play"  pauseState) {
    3.         Time.timeScale = 0.0;
    4.       Instantiate (pauseMenu);
    5.     }
    6. }
     
  22. marjan

    marjan

    Joined:
    Jun 6, 2009
    Posts:
    563
    Interesting that you come so far...
    I am just testing a unity3 upgraded project and it seems the app. crashes when opened again after being closed for a longer time, some hours or so. As this is really hard to debug, i am thinking to not allow this ios4 Feature. (there is a Way to Toggle this in the info.plist)
     
  23. Moonjump

    Moonjump

    Joined:
    Apr 15, 2010
    Posts:
    2,572
    UIApplicationExitsOnSuspend is looking like the route to go at the moment.