I was wondering what you can do to reduce the memory footprint of your app when the user unfocuses it.
As of now my app uses up to 250 MB and is often killed when in background. The average ‘level’-cycle is 10 minutes or more. If the user does whatsapp or anything memory-taxing in between, he will most likely loose his levelprogress.
I was thinking of something like disabling all cameras and then unloading all textures. Afaik unity loads textures only after a material is shown for the first time, so you get that lag on enabling a menu for the first time.
I imagine if i can do this the other way around, before the app loses focus, i can get the memory down significantly while in background, only suffering a reload-lag when refocusing the app.
A little ‘hack’ you can do is write a plugin that registers a Notification to the System tray. This will give your app priority when it does memory trashing and it won’t close your app. Now, this isn’t a guaranteed solution as the Android kernel will kill your app, notification tray or not, if it really really needs the memory.
If the android device needs the memory, it will kill your app anyway.
My suggestions are:
-Save the state of the level on the pause
-Reduce the memory usage , scale down the textures
-Free any resources that you no longer need on that level. For example, if you won’t see any purple enemies. Release the resources associated to the purple enemies so the GC can do his job
Free resources: That is hard to do, on one side i want most things to batch, on the others side i need the references to their prefabs. AFAIK, as long as anything references a prefab, Resource.UnloadUnusedAssets will not pick up the mesh, materials, or textures of this prefab, so it stays in memory. The other options are AssetBundles and the Resource folder, but the stuff from there cannot be batched so i would increase draw calls.
Correct?
I think i will get down to 20MB texture memory after finalizing all textures ( currently its 90MB with all the testing stuff that will be removed, game is polystyle, only real textures are UI).
That would be the best solution of course but i worry about save game corruption and other problems:
I imagine the serialization would take some seconds on slower devices and that android would kill the application too if it takes to long to put to sleep (true?). I already use a XML deserializer and that thing takes like 400ms on first deserialization of a small serialized class.
I just think i would fail with serializing this game. I use lots of events and lambda stuff. Are event subscriptions serialized easily? Are local lambda subscriptions saved? I even use threads, what if a thread isn’t finished on defocus? Some of them run for several frames in background.
If you still need the references to the prefabs, one way could be to “re design” the prefabs use in your code, but I don’t think it worth the time, I didn’t work with AssetBundles so I don’t know how it is being handle so I am unable to help you there sorry.,
1: JSON is faster than XML in my experience and test, anyway stated from android activity lifecycle doc
You can use OnStop in order to save your level to be sure that it has been saved, however It is no 100% Safe ( since slow devices can give an ANR while your app use OnStop and the user can kill the app) but almost safe.
Personally, I will like to save the state of every “entity” and then when you resume the game , let the entity sucribe again to events based on his “state”. I don’t use lambda neither so I don’t know about that.
Take care with background threads some manufacturers like Huawei kill backgrounds threads when they want to.
Anyway I think that the 1 option is over- kill solution. If you have millions of users maybe you should go for it but If that is not the case I will go for the 2 option and let some really slow devices to lose their progress level (measuring the impact of course)