👋 Hi there, I'm HoangVanThu. This repository discusses various ways to optimize your games on mobile devices, helping enhance overall performance. These techniques aim to improve the gaming experience by optimizing resource usage and performance on mobile platforms.
The article has been synthesized from various sources on the internet. If you find any inaccuracies or have any questions about the content, please submit an issue or provide direct feedback to me.
- Most of your memory will likely go to textures, so the import settings here are critical. In general, try to follow these guidelines:
- Lower the Max Size: Use the minimum settings that produce visually acceptable results. This is non-destructive and can quickly reduce your texture memory.
- Use powers of two (POT): Unity requires POT texture dimensions for mobile texture compression formats (PVRCT or ETC).
- Atlas your textures: Placing multiple textures into a single texture can reduce draw calls and speed up rendering. Use the Unity Sprite Atlas or the third-party TexturePacker to atlas your textures.
- Toggle off the Read/Write Enabled option: When enabled, this option creates a copy in both CPU- and GPU-addressable memory, doubling the texture’s memory footprint. In most cases, keep this disabled. If you are generating textures at runtime, enforce this via Texture2D.Apply, passing in makeNoLongerReadable set to true.
- Disable unnecessary Mip Maps: Mip Maps are not needed for textures that remain at a consistent size on-screen, such as 2D sprites and UI graphics (leave Mip Maps enabled for 3D models that vary their distance from the camera).
- Compress Texture: For almost every mobile device today, format should be RGBA Compressed ASTC. For older devices, you can choose ET2 or ETC compress.
- Texture compression format: Player Settings provide a global default for texture compression, affecting all textures unless overridden.
- ETC (Default): ETC (Ericsson Texture Compression) is a common format used on Android devices.
- ASTC: ASTC (Adaptive Scalable Texture Compression) is a modern texture compression format suitable for a variety of platforms, including newer mobile devices.
- Alway enable Force to mono to reduce the file size, use less memory and many other advantages.
- Reduce the size of your clips and memory usage with compression:
- Use Vorbis for most sounds (or MP3 for sounds not intended to loop).
- Use ADPCM for short, frequently used sounds (e.g., footsteps, gunshots). This shrinks the files compared to uncompressed PCM, but is quick to decode during playback.
- Sound effects on mobile devices should be 22,050 Hz at most. Using lower settings usually has minimal impact on the final quality; use your own ears to judge.
- The setting varies by clip size.
- Small clips (< 200 kb) should Decompress on Load.
- Medium clips (>= 200 kb) should remain Compressed in Memory.
- Large files (background music) should be set to Streaming.
- Much like textures, meshes can consume excess memory if not imported carefully. To minimize meshes’ memory consumption:
- Compress the mesh
- Disable Read/Write
- Disable rigs and BlendShapes
- Disable normals and tangents
- You can change properties such as rotation error, position error, and scale error to reduce file size.
- Be cautious because these parameters introduce animation errors.
- Your game may have many code redundancy, so clean code could increase the performance for your game.
- Here I found a good clean code topic.
Every time an object is created, memory is allocated.
- String concatenation creates garbage.
- Debug.Log("hello" + " " + "world");- This code above will create 3 difference string and located in the heap memory. So this should be:
+ Debug.Log("hello world");- Structs = stack, Classes = heap
- Structs are faster for small data
- Classes are better for complex objects
- UnityEvent is slower and generates garbage.
- The algorithm will significantly improve the performance of the game, apply it whenever possible.
- Imagine 100 enemies moving in the same direction at the same speed. If each enemy has its own Update method, Unity must call the same logic 100 times every frame, creating unnecessary overhead. By using a single centralized update to move all enemies together, the engine work is reduced, performance improves, and the system scales better.
- This approach is commonly known as a Centralized Update (or Manager-based) pattern, where multiple entities are updated through a single update loop instead of each entity having its own
Updatemethod.
- Because
Destroy(GameObject)is expensive and generates garbage memory, frequently creating and destroying objects can cause performance spikes and GC stuttering, especially on mobile devices. Object Pooling avoids this cost by reusing existing objects instead of destroying them, resulting in more stable performance, fewer GC allocations, and smoother gameplay.
- Avoid creating 9999 UI items, reuse them instead.
-
Mobile games typically target 60 FPS (frames per second) — this is the most comfortable and responsive framerate for players. Unity’s Physics system uses Fixed Timestep, which by default updates every 0.02 seconds, equivalent to 1 second / 60 frames.
-
However, when launching your game in many different markets, you will encounter a wide range of low-end devices. To optimize performance for these weaker devices, you can safely set Fixed Timestep = 0.033s, which corresponds to 30 FPS. You can also retrieve the device’s hardware specifications and dynamically adjust the FPS in your code accordingly.
-
In Unity, all physical interactions are processed through object layers and colliders. Having too many colliders interacting unnecessarily will degrade your game’s performance. Therefore, you should optimize by organizing your layers and colliders properly.
-
If two layers do not need to interact, disable their interaction immediately in the Layer Collision Matrix so the Physics system doesn’t waste time checking them. Additionally, in newer versions of Unity, each collider can individually exclude specific layers that it should not interact with.
- Avoid Tech Stream for stability.
- Avoid double compression quality loss.
- Every active Audio Source consumes CPU/RAM.
- Gamma = 10–30% faster.
- Smoother GC in some cases.
- Reduce triangles for distant meshes.
- Reduce draw calls by combining meshes.
- Disable real shadows → huge performance gain.
- Use Sprite Atlas for batching.
- Reduce draw calls for repeated meshes.
- Avoid FPS lock + battery drain.
- Use GLES2 + GLES3 for compatibility.
- Topics:
- Also, I have created a simple game system for mobile platform:
- If you like this topic, you can give this repository a star ⭐
- I would greatly appreciate it if you could support me with a cup of coffee












