In the editor your game runs smoothly. Then you install the build on your own phone and suddenly everything feels sluggish. The camera lags behind, menus respond slowly, and after ten minutes of play the device feels warm in your hand. Almost every Unity team hits this moment at some point, usually just before a release.
The good news: for most projects this is no reason to rewrite systems. Often all that is missing are a few deliberate decisions about frame rate, resolution, render pipeline and textures. This article answers the question of how to optimize your Unity game for Android and iOS in a fixed order. First you measure on the device, then you adjust the settings in Unity 6 and URP that the Unity documentation lists as having the biggest impact. At the end there is a checklist you can work through right away.
Measure First, and Do It on the Device
The editor runs on your development machine. That is why it tells you little about how a mid-range phone behaves. Mobile devices have different GPUs, less memory bandwidth, and throttle their performance when they get warm. So before you change any setting, you should know where the time is actually being lost.
This is how you connect the Unity Profiler to your device:
- Open File > Build Profiles and select Android or iOS.
- Enable Development Build and Autoconnect Profiler.
- Start the build with Build & Run.
- In Unity, open Window > Analysis > Profiler. The device appears in the target selection at the top of the window.
On Android over a USB cable, the device shows up there as an entry like AndroidProfiler([email protected]:34999). If the network connection does not work, check your firewall. Unity lists ports 54998 to 55511 for this. For GPU questions, the URP documentation also recommends a GPU profiler such as RenderDoc or Xcode.
A tip from our own practice: before every change, record a baseline measurement in a fixed test scene. That is the only way to see later which setting really helped and which one you could have skipped.
Set the Frame Rate on Purpose
Why Your Game Runs at 30 FPS on Phones
Many teams wonder why their game never gets above 30 FPS on a phone, even though the Profiler still shows headroom. The answer is in the Unity documentation for Application.targetFrameRate. On Android and iOS, with the default values QualitySettings.vSyncCount = 0 and Application.targetFrameRate = -1, Unity renders at a fixed 30 frames per second. This conserves battery power and applies regardless of the display's refresh rate. On these platforms Unity ignores vSyncCount values greater than zero.
Two more details from the documentation matter. Unity never renders faster than the display allows. And values that do not evenly divide the current refresh rate are rounded down to the nearest value that does. The example from the docs: on a 60 Hz display, a target of 25 actually results in 20 FPS.
Code Example: Set the Frame Rate at Startup
A small script in your first scene is enough:
using UnityEngine;
public class MobileFrameRate : MonoBehaviour
{
[SerializeField] private bool useNativeRefreshRate = false;
[SerializeField] private int targetFrameRate = 60;
private void Awake()
{
// targetFrameRate only applies when vSyncCount is 0
QualitySettings.vSyncCount = 0;
Application.targetFrameRate = useNativeRefreshRate
? (int)Screen.currentResolution.refreshRateRatio.value
: targetFrameRate;
}
}
The refreshRateRatio variant matches the approach Unity describes for using the display's native refresh rate. On iOS, ProMotion also comes into play. If ProMotion is disabled in the project, which is the default for new projects, the native rate is 60 Hz. If it is enabled, 120 Hz is possible on supported displays.
More is not automatically better here. Unity itself points out that a lower frame rate conserves battery life and avoids overheating. From our practice: an action game benefits noticeably from 60 FPS, while a calm puzzle or card game can deliberately stay at 30. Decide this per game, not out of habit.
Optimized Frame Pacing on Android
In the Android Player Settings, under Resolution and Presentation, you will find the option Optimized Frame Pacing. According to the documentation, Unity then distributes frames more evenly, so the frame rate varies less and the game feels smoother.
Render Fewer Pixels
Modern phones have very high resolutions. But every pixel has to be computed. Unity's Android documentation states explicitly that a resolution below the device's native resolution can improve performance and battery life. There are two ways to do this.
Render Scale in the URP Asset
In the URP Asset, under Quality, you will find the Render Scale slider. It scales the resolution at which the game image is rendered. According to the documentation, the UI stays at native resolution and therefore sharp. The Upscaling Filter controls how the smaller image is brought up to display size. One of the options is AMD FidelityFX Super Resolution 1.0.
Code Example: Adjust Render Scale at Runtime
Not every device needs the same value. The Unity documentation shows how to find the active URP Asset at runtime and set properties such as renderScale and shadowDistance based on graphics memory. A shortened version:
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
public class MobileRenderScale : MonoBehaviour
{
private void Start()
{
var urp = GraphicsSettings.currentRenderPipeline as UniversalRenderPipelineAsset;
if (urp == null) return;
int vram = SystemInfo.graphicsMemorySize;
if (vram <= 1024)
{
urp.renderScale = 0.7f;
urp.shadowDistance = 50f;
}
else if (vram <= 3072)
{
urp.renderScale = 0.9f;
urp.shadowDistance = 150f;
}
}
}
The numbers come from the Unity example and are a starting point, not a recommendation. Only measurements on real devices give you the right values for your game. A note from our practice: in the editor, a script like this changes the URP Asset itself. After a test run in Play Mode, check that your asset still has the starting values you want.
Fixed DPI on Android
Alternatively, in the Android Player Settings under Resolution Scaling, you can set Resolution Scaling Mode to Fixed DPI and enter a Target DPI. If the display has a higher pixel density, Unity scales the resolution down. The formula from the documentation is min(Target DPI × Factor / Screen DPI, 1). The Factor comes from the Quality settings, where it is called Resolution Scaling Fixed DPI Factor.
Configure the URP Asset for Mobile
For mobile devices it pays to have a separate URP Asset that you assign to the mobile quality level. How to organize quality levels cleanly for different hardware is covered in our article on cross-platform development with one codebase and four hardware profiles. Here we focus on the individual switches.
The Unity page "Configure for better performance in URP" lists the settings with the biggest impact. These are especially relevant for mobile:
- Disable HDR, or if you need HDR, use 32-bit precision. This saves memory.
- Depth Texture and Opaque Texture: only enable them if a shader or effect really needs them.
- Set Store Actions to Auto or Discard. According to Unity, URP then avoids using memory bandwidth on lower-end mobile devices to copy render targets into and out of memory between passes.
- Reduce or disable anti-aliasing (MSAA) to save memory bandwidth.
- Enable the SRP Batcher once you have checked that your shaders are compatible.
- Set Additional Lights to Per Vertex or Disabled if you use the Forward path. Turn off shadows for additional lights.
- Make shadows cheaper: lower shadow map resolution, shorter Max Distance, fewer cascades, and Soft Shadows off.
- Disable LOD Cross Fade on lower-end mobile devices.
- Set Depth Priming Mode to Disabled for mobile platforms.
- Enable Native RenderPass if you use Vulkan or Metal.
- Use few cameras, because every camera costs culling and rendering.
For shaders, Unity recommends Baked Lit for static objects and Simple Lit for dynamic objects on lower-end mobile devices. Avoid the expensive Complex Lit shader.
Do not change all of these at once. Unity itself recommends measuring the effect of each setting with the Profiler or a GPU profiler. Your project might need some of these features after all.
Post-Processing in Moderation
According to Unity, post-processing can take up a lot of frame time. The URP documentation lists these effects as the most "mobile-friendly" by default:
- Bloom with High Quality Filtering disabled
- Chromatic Aberration
- Color Grading
- Lens Distortion
- Vignette
For depth of field on lower-end devices, Unity recommends Gaussian mode.
Bloom is popular on mobile, so its settings are worth a look. According to the Bloom reference, these are the key levers: turn High Quality Filtering off, choose the faster Dual or Kawase Filter, set Downscale to Quarter, and lower Max Iterations.
Screen Space Ambient Occlusion (SSAO) in URP is not a volume effect but a Renderer Feature, and it does not appear in the list above. If you want to use SSAO on mobile, check the settings on Unity's Ambient Occlusion page carefully and measure the difference on the device.
Make Overdraw Visible
Overdraw means the same pixels are drawn several times in one frame. On mobile devices this is expensive because memory bandwidth is limited. Unity ships the Rendering Debugger for this. Open it via Window > Analysis > Rendering Debugger and enable the Overdraw view. It shows where Unity draws pixels over one another.
The Rendering Debugger also works on the device. In a Development Build you open it on the touchscreen with a three-finger double tap. For all sections to be available in the build, the documentation says the Strip Debug Variants option in the URP Global Settings must be disabled.
In our practice, the usual culprits are large semi-transparent particles, fog and smoke sprites that cover half the screen, and full-screen UI panels stacked on top of each other even though only the top one is visible.
Textures and Download Size
ASTC as the Default Format
Uncompressed or wrongly compressed textures cost memory and bandwidth. The Unity documentation recommends ASTC for iOS devices with an A8 chip or later and for modern Android GPUs. The fallback matters: if a device does not support ASTC, Unity decompresses the texture to uncompressed RGBA 32-bit. That costs additional memory and loading time.
In the Android Player Settings you can add several formats under Texture compression formats. With an App Bundle for Google Play, Unity then uses texture compression targeting, and each device receives the right format. If you build an APK, the documentation says Unity only uses the first format in the list.
The Truth About the 200 MB Limit
Forums often claim that an Android game has to stay under 200 MB. That is no longer accurate. According to Google Play, the limit for the compressed download size of the base module is 500 MB. The 200 MB still matter, though: if the download is larger, users on mobile data see a notice about the size. The notice does not block the installation, but it can put users off. Unity's own Play Asset Delivery page still mentions 200 MB, but Google's information is what counts here.
For larger content there is Play Asset Delivery. Google offers three delivery modes:
- install-time: the content comes with the installation.
- fast-follow: the content downloads automatically right after installation.
- on-demand: the content downloads only when the game requests it.
In Unity 6 the easiest way to connect this is the Addressables for Android package, which packs Addressables groups into asset packs. On iOS, Apple's limit is considerably higher, and for additional content after installation Apple offers the Background Assets framework.
Shrink the Build
A few switches in the Android Player Settings make the build smaller:
- Strip Engine Code (IL2CPP only) removes engine code for features your project does not use.
- Managed Stripping Level controls how aggressively unused C# code is removed. According to Unity, higher levels can also remove code that is in use, so test thoroughly.
- Texture Mipmap Stripping removes mipmap levels at build time that no quality level of the platform uses.
- Optimize Mesh Data strips unused vertex attributes. Unity warns that with this option enabled you should not change material or shader settings at runtime.
Keep an Eye on Heat and Battery
A game that runs smoothly for the first few minutes can drop later because the device throttles its performance when it gets hot. The Android Player Settings offer Sustained Performance Mode for this. According to the documentation, it provides predictable, consistent performance over longer periods without thermal throttling. Overall performance might be lower, though.
Adaptive Performance goes one step further. The package provides information about the device's thermal state, and your game can react to it, for example by lowering quality levels. The feature set differs by platform. According to Unity, both the Android and the Apple provider support thermal warnings and scalers. Automatic performance control (Auto Performance Control) is only available with the Android provider. To get started, it is enough to know these tools exist. The basics in this article should come first.
Checklist: Mobile Optimization in Six Steps
- Profile on the device. Development Build with Autoconnect Profiler, a fixed test scene, and a recorded baseline.
- Set the frame rate on purpose. Choose
Application.targetFrameRateto fit your game type and enable Optimized Frame Pacing on Android. - Render fewer pixels. Use Render Scale in the URP Asset or Fixed DPI on Android.
- A separate URP Asset for mobile. Configure HDR, MSAA, shadows, Additional Lights and Store Actions following Unity's list.
- Trim post-processing and check overdraw. Prefer mobile-friendly effects and use the Rendering Debugger on the device.
- Keep textures and downloads under control. Use ASTC, texture compression targeting, Play Asset Delivery and stripping.
And after every step: measure again.
Conclusion
Optimizing a Unity game for Android and iOS is rarely about tricks. It is about order. If you measure on a real device first, set the frame rate on purpose, render fewer pixels and maintain a separate URP Asset for mobile, you already hold the biggest levers. Lean post-processing, little overdraw, ASTC textures and Play Asset Delivery take care of the rest. And the 200 MB on Google Play are no longer a hard limit but the threshold for a notice to users on mobile data.
A practical next step: build a Development Build today, connect the Profiler, and check the frame rate your game actually runs at. If the Profiler also shows stutters from frequent spawning, our tip on object pooling in Unity will help. And if you need support optimizing your mobile game, ProjectMakers is there for you with our game development services.