The development of cross-platform projects has become an industry standard, and the Unity engine provides powerful tools for this. The process of transferring a ready-made project from a personal computer to mobile devices running Android seems complicated only at first glance. In fact, most of the changes concern not the code, but the optimization of resources and redesign of the input system.
The main difficulty lies in the fundamental difference in architectures. Desktop version relies on high computing power and the presence of a physical keyboard, while the mobile platform is limited by the thermal package of the processor and the touch screen. You will have to adapt the interface, compress textures and reconfigure the physics engine to work on less powerful chips.
In this guide we will go through the entire path from the moment you open the project to receiving the finished APK file. You will learn about the intricacies of setting up Gradle, features of working with IL2CPP and methods for reducing energy consumption. Proper preparation at the porting stage will save you weeks of debugging on real devices.
Preparing the environment and setting up Build Settings
The first step is to install the necessary modules through Unity Hub. Without the installed module Android Build Support, which includes Android SDK and NDK, compilation is impossible. After installing the components, you need to go to the menu File โ Build Settings and switch the platform by pressing the button Switch Platform.
This process may take a significant amount of time as the engine recompiles assets for the new processor architecture. In the settings window that opens, it is important to pay attention to the field Package Name. It must be unique and match the reverse domain format, for example com.yourname.projectname, otherwise Google Play Console will reject the download.
โ ๏ธ Attention: Make sure that the paths to the Java JDK are correctly set in your operating system environment variables. Using Java versions newer than those supported by Unity often leads to Gradle build errors.
Next, you should select the minimum API version. Setting the value too low (API Level) will expand the audience, but will deny access to modern system functions. The best choice at the moment is Android 7.0 (API 24) or higher, which covers the vast majority of active devices.
The screen orientation is also adjusted in this section. For most games, it is preferable to lock the landscape mode and disable auto-rotate to avoid redrawing the interface at inopportune moments. This is especially critical for fast-paced action games, where every millisecond of rendering matters.
Adaptation of controls and interface (UI)
The most obvious difference in mobile gaming is the absence of a physical keyboard and mouse. You will have to completely rewrite the input logic, replacing events KeyDown and GetMouseButtonDown with touch processing. Unity offers a system Input Systemthat allows you to flexibly map actions to different controllers.
To implement virtual joysticks and buttons, it is best to use ready-made assets or standard elements Unity UI.
The interface dimensions must be tied to safe zones (Safe Area). On modern smartphones with notches and camera cutouts, the standard UI may be cut off. Using the component Canvas Scaler in mode Scale With Screen Size will ensure correct display on screens with different aspect ratios.
Don't forget to add multi-touch support. Unlike a PC, where usually one cursor is active, several fingers can be on the screen at the same time. Handling multi-touch gestures such as zooming or swiping will significantly improve the user experience.
Use translucent textures for control buttons so that the player can see the gameplay under their fingers, but understand where the click zone is.
Optimizing graphics and performance
Mobile processors have strict limits on energy consumption and heat dissipation. If a game on a PC can consume 150 Watts, then a smartphone, when the threshold of 3-5 Watts is exceeded, will begin to throttle, dropping frequencies and causing lags. The key parameter here is the number of draw calls (Draw Calls).
To reduce the load, actively use batching. Static batching combines stationary objects, and dynamic - moving ones, although the latter requires more CPU processing power. Using texture atlases (Texture Atlasing) allows you to pack many small images into one, minimizing switching textures.
Texture resolution is another critical resource. Textures of 4096x4096 size, acceptable for a PC, on a mobile device will take up a huge amount of RAM and can crash the application. It is recommended to use compression ASTC or ETC2, which effectively reduces the weight of the graphics without significant loss. quality.
Lighting also requires revision. Dynamic shadows and real-time light are extremely resource-intensive. On mobile platforms, it is preferable to bake light (Baked Lighting) into lighting textures, which transfers the load from the processor to the video card and significantly increases FPS.
| Parameter | PC (High Settings) | Android (Optimization) | Influence |
|---|---|---|---|
| Shadows | Soft Shadows, High Res | Hard Shadows or Baked | Reducing GPU load |
| Polygons | 500k - 2M+ | 10k - 50k per scene | Rendering speed |
| Textures | Uncompressed / BC7 | ASTC 4x4 / 6x6 | Consumption memory |
| Post-processing | Full stack effects | Minimum / Disabled | FPS stability |
โ๏ธ Optimization checklist
Working with memory and resource management
RAM on mobile devices is a scarce resource. Unlike a PC, where running out of RAM will only lead to the use of the page file, on Android the operating system will simply โkillโ your application. Profiler Unity (Window โ Analysis โ Profiler) is your main tool for finding leaks.
Pay special attention memory allocations in the loop Update. Creating new objects, strings or arrays every frame causes the garbage collector to run frequently (Garbage Collector). This causes micro-stuttering, which feels like severe stuttering on a mobile device.
โ ๏ธ Attention: Avoid using LINQ and regular expressions in the game loop. They create a significant amount of temporary garbage in the heap, which provokes frequent engine stops to clean up memory.
To control the loading of levels and heavy assets, use additive loading of scenes. Instead of one giant map, it is better to break the game into small segments that load as the player progresses. This allows you to unload unused resources and free up memory.
Object pooling (Object Pooling) is a must-have technique for mobile games. Instead of creating and destroying bullets or enemies, create a pool in advance and simply turn them on and off as needed. This dramatically reduces the load on the processor and memory.
What is Garbage Collector?
Garbage Collector is an automatic memory management system in .NET and Unity. When free memory becomes low, it pauses code execution to find and remove unused objects. On mobile devices, this pause can last from 10 to 100 ms, which at 60 FPS (16 ms per frame) causes a noticeable freezing of the picture.
Setting up sound and multimedia
The audio system also requires adaptation. PC audio compression formats (such as uncompressed WAV or PCM) take up too much space and memory bandwidth. For mobile platforms, the standard format is Vorbis with a bitrate of 128 kbps or lower for background music.
It is important to configure the settings Audio Source. For short sound effects (gunshots, steps), use the Decompress On Loadmode to avoid delays during playback. For long tracks of background music, on the contrary, select Streamingso as not to load the entire track into RAM at once.
Do not forget about system sound limitations. On many devices, audio may not play if the silent switch is active or if an app is minimized. Correct event processing OnApplicationPause will allow you to pause audio when minimizing the game, which is good manners and saves battery.
Building, (Signing) and testing
The final stage is creating an installation file. In the settings Player Settings you need to create or select Keystore. This is a digital key that confirms the authorship of the application. Without it, you will not be able to update the game on Google Play if you lose the original key.
For assembly, select the archive type APK (for direct testing) or Android App Bundle (AAB) (required for publication on Google Play). AAB allows the store to optimize the download size for a specific user device, cutting off unnecessary processor architectures.
adb install -r path/to/your/game.apk
This command via Android Debug Bridge will install the assembled game on the connected device. You need to test not only on an emulator, but also on real hardware devices from different manufacturers, since video card drivers (Adreno, Mali, PowerVR) can behave differently.
Use logging via Debug.Log to track errors on the device. The window Window โ General โ Device and Simulation allows you to see the console of the connected smartphone in real time directly in the Unity editor.
Publishing on Google Play requires signing the AAB file with a unique Keystore key. Never lose your password and storage file, otherwise it will be impossible to restore access to updating the application!
Why does the game crash immediately after launching on Android?
Most often, the reason lies in the lack of support for a specific processor architecture (for example, the build is only for x86, and the phone requires arm64) or in a script error that is executed at startup. Check the logs via Logcat.
How to reduce the size of an APK file?
Use the Android App Bundle (AAB) format, enable resource compression (LZ4 or Zip), delete unused assets and select only the necessary processor architectures (usually arm64-v8a is enough).
Need Is it possible to rewrite the code in C# for Android?
In 95% of cases there is no need to rewrite the code. Unity compiles C# into native code for the target platform. The changes relate mainly to working with file paths, input and optimization.