Returning to app in multitasking

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?

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?

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

What can I do as a reaction to the OnApplicationPause?

I tried;

function OnApplicationPause () {
	Time.timeScale = 0.0;
    Instantiate (pauseMenu);
}

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.

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.

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.

Don’t think so, there’s always a slight delay (which happens during the fade out effect).

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.

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.

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:

if (Input.GetButtonDown ("Home"))

Here is the request if anyone would also like the feature:

http://feedback.unity3d.com/forums/15792-unity/suggestions/1084259-iphone-home-button-press-detection

I don’t think they can. I think it’s iOS thing. Not entirely sure though.

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.

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

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)

function OnApplicationPause (pauseState : boolean) {
	if (gameActive == "play"  pauseState) {
		Time.timeScale = 0.0;
      Instantiate (pauseMenu);
	}
}

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

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.

Not that I really expected it to, but Unity 3f3 does not solve the problem.

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.

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.

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?