U
tab 05Export to Mobile7 lessons — tap to open
07 / 07 · 26 min
Export to Mobile★ exercise

Final exercise: ship the game

your project so far▸ Arena.unity

everything from tab 01–05 · signed release build on a real phone

exercise3–5 h

The final exercise of the course: put the Arena — waves, enemies, touch controls and all — on a real phone as a signed release build that holds its frame rate for five minutes (60 FPS where the phone can, never below 30) and remembers your progress when you kill the app.

what you reuse

Everything from tabs 01–04Android build setupPlayer SettingsURP mobile qualitySave / load JSONadb logcatKeystore + .aab
animated diagram

Not a screenshot in the editor — an app icon on a phone that someone else could install.

Part 1 — clean up the scene

  • Open Arena.unity — the scene you have been growing since tab 01 — and check the GameDirector still has its spawn points.

  • Delete anything left over from testing: spare cameras, stray lights, blocks you moved aside.

  • There must be exactly one AudioListener, one EventSystem and one CinemachineBrain in the scene.

  • Check the touch canvas from tab 03 is still there and switches itself on when the game runs on a phone.

Part 2 — configure the build

the settings you must change
Project Settings → Player
  Company Name            your studio               // not DefaultCompany
  Product Name            Arena
  Package Name            com.yourstudio.miniarena  // permanent
  Version / Bundle Code   1.0.0 / 1
  Default Orientation     Landscape Left
  Scripting Backend       IL2CPP
  Target Architectures    ARMv7 + ARM64             // ARM64 is mandatory
  Minimum API Level       24
  Managed Stripping       Medium
  Graphics APIs           Vulkan, OpenGLES3         // remove OpenGLES2

URP Asset (mobile)
  Shadow Max Distance     40
  Cascade Count           1
  HDR                     off
  MSAA                    disabled
  Render Scale            0.85

Assets/link.xml
  preserve SaveData       // or stripping deletes it
MobileBoot.cs — must exist in the first scene
void Awake()
{
    Application.targetFrameRate = 60;
    QualitySettings.vSyncCount = 0;
    Screen.sleepTimeout = SleepTimeout.NeverSleep;
    DontDestroyOnLoad(gameObject);
}

Part 3 — the first build is always broken

Expect it. Build a Development Build first, install it, and read adb logcat while you play. The bugs that only exist on device are the whole point of this exercise.

terminal
adb devices                          # is the phone actually connected?
adb logcat -c && adb logcat -s Unity # clear, then watch only Unity

# after the build
adb install -r Builds/arena-dev.apk
adb shell monkey -p com.yourstudio.miniarena 1

The five bugs almost everyone hits

  • Pink materials — a shader did not convert to URP. Convert the materials, rebuild.

  • Buttons do nothing — no EventSystem, or an invisible full-screen Image is eating the raycasts.

  • Save file empty — IL2CPP stripping removed SaveData. Add it to link.xml.

  • 20 FPS on device, 200 in the editor — realtime shadows and post-processing. Check the URP asset.

  • UI cut off by the notch — the safe area fitter is missing on the touch canvas.

Part 4 — the release build

  • Create a keystore, save it OUTSIDE the project, back it up twice. Losing it can lock you out of updating the app.

  • Add *.keystore to .gitignore before you commit anything.

  • Untick Development Build, tick Build App Bundle, and build the .aab.

  • Also keep a signed .apk — that is the one you hand to a friend to test.

Done when

  • ✓The app is installed on a physical phone, launched from its own icon, not from Unity.
  • ✓You can complete a full loop with touch alone: move, aim the camera, cast all three skills, kill an enemy.
  • ✓Every UI element is inside the safe area on a phone with a notch, and anchored so a tablet does not break it.
  • ✓Backgrounding the app and force-closing it, then reopening, restores your health, position and gold.
  • ✓Five minutes of continuous play stays at or above 30 FPS — measured at minute five, not minute one.
  • ✓adb logcat -s Unity shows no exceptions during a full play session.
  • ✓A signed .aab exists, built with Development Build unticked.
  • ✓Someone else installed your .apk on their phone and it ran.

Numbers to hit

MetricTargetWhy
FPS at minute 5≥ 30Thermal throttling makes minute 5 the only honest measurement.
Build size (.aab)≤ 150 MBAbove 150 MB Google Play needs extra delivery configuration.
Cold start to playable≤ 5 sPlayers close apps that show a black screen for longer.
Memory in use≤ 600 MBAbove that a 3 GB phone starts killing your app in the background.
Exceptions in logcat0One NullReference per frame is a silent frame-rate killer.

If you want more

bonus 1

Upload the .aab to Play Console as an internal test and install it from the Play Store on your own phone.

bonus 2

Add a device-tier check that drops render scale and shadow distance on phones with under 3 GB RAM.

bonus 3

Build the same project for iOS and compare the frame rate on similar hardware.

bonus 4

Add an in-game FPS + memory overlay you can toggle, so testers can report real numbers.

That is the whole course

  • You started at 'what is a variable' and finished with a signed build on a phone. That is the entire pipeline.

  • Everything after this is depth, not breadth: better animation, smarter enemies, real level design, a real art style.

  • The next thing to build is a game with one mechanic and five minutes of content that you actually finish. Finishing is the rarest skill in this field.