惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

J
Java Code Geeks
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
V
V2EX
小众软件
小众软件
WordPress大学
WordPress大学
Apple Machine Learning Research
Apple Machine Learning Research
Recent Announcements
Recent Announcements
有赞技术团队
有赞技术团队
MongoDB | Blog
MongoDB | Blog
C
Check Point Blog
S
Schneier on Security
C
Cybersecurity and Infrastructure Security Agency CISA
The Cloudflare Blog
V
Vulnerabilities – Threatpost
The Hacker News
The Hacker News
T
Threatpost
T
Tenable Blog
aimingoo的专栏
aimingoo的专栏
IT之家
IT之家
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
C
CERT Recently Published Vulnerability Notes
U
Unit 42
Spread Privacy
Spread Privacy
博客园 - 司徒正美
Hacker News: Ask HN
Hacker News: Ask HN
C
CXSECURITY Database RSS Feed - CXSecurity.com
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
阮一峰的网络日志
阮一峰的网络日志
SecWiki News
SecWiki News
云风的 BLOG
云风的 BLOG
The Register - Security
The Register - Security
AWS News Blog
AWS News Blog
月光博客
月光博客
Security Latest
Security Latest
H
Heimdal Security Blog
S
Secure Thoughts
博客园 - 聂微东
PCI Perspectives
PCI Perspectives
博客园 - 叶小钗
Scott Helme
Scott Helme
O
OpenAI News
Google DeepMind News
Google DeepMind News
Google DeepMind News
Google DeepMind News
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
S
Security @ Cisco Blogs
NISL@THU
NISL@THU
S
Securelist
Latest news
Latest news
P
Proofpoint News Feed
博客园 - 【当耐特】

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Mobile Game Optimization: A Unity Developer's Checklist
Ocean View Games · 2026-05-25 · via DEV Community

Ocean View Games

Every Unity developer has had the same sinking feeling: the game runs beautifully in the Editor on a development machine, but the moment it hits a real mobile device, frame rates crater, the phone overheats, and the battery drains in minutes.

Mobile optimization is not something you bolt on at the end. It is a discipline that needs to run through every stage of development. But even with the best intentions, performance issues creep in. Draw calls accumulate. Textures bloat. Garbage collection spikes appear in the profiler like clockwork.

At Ocean View Games, mobile performance is core to what we do. From our work on Domi Online - rendering 10,000+ GPU-instanced trees with minimal draw calls - to our founder's experience optimizing RuneScape for mobile hardware during his tenure at Jagex, we have developed a systematic approach to mobile optimization that we apply to every project.

This post is the checklist we use internally. It is practical, actionable, and organized by the order you should tackle things - starting with profiling (because you should never optimize blind) and working through the most impactful areas.


Step 0: Profile First, Optimize Second

This is the most important rule on this entire list. Never optimize based on intuition. Profile on real hardware, identify the actual bottleneck, and fix that specific problem.

The Profiling Toolkit

  • Unity Profiler - Your primary tool. Use the CPU, GPU, Memory, and Rendering modules. Connect to your device via USB or WiFi for real hardware data. Editor profiling gives misleading results.
  • Frame Debugger - Shows exactly what Unity is rendering each frame and in what order. Essential for identifying redundant draw calls and overdraw.
  • Memory Profiler - A separate package (install from Package Manager) that provides detailed snapshots of managed and native memory. Use it to track texture memory, mesh data, and AudioClip allocations.
  • Xcode Instruments (iOS) - Metal System Trace and Allocations instruments give GPU-level detail that Unity's profiler cannot.
  • Android GPU Inspector / Snapdragon Profiler - For Android-specific GPU profiling, especially on Qualcomm chipsets.

What to Look For

Before you touch any code, answer these questions:

  1. Are you CPU-bound or GPU-bound? The Unity Profiler's timeline view shows this clearly. If the CPU frame time exceeds the GPU frame time, your bottleneck is scripts, physics, or animation - not rendering.
  2. Where are the spikes? Smooth 30fps with periodic 200ms spikes is a different problem than a consistent 20fps. Spikes usually indicate garbage collection or expensive one-off operations.
  3. What is the memory footprint? Mobile devices have hard memory limits. Exceeding them causes an instant, silent crash with no error log.

Key Takeaway: Always profile on the lowest-spec device you intend to support. A game that runs at 60fps on an iPhone 15 Pro and crashes on a 3-year-old Android is not optimized - it is untested.


Rendering and Draw Calls

Rendering is the most common bottleneck in mobile Unity games. Every draw call has CPU overhead, and mobile GPUs have strict limits on what they can process per frame.

The Draw Call Checklist

  • [ ] Enable Static Batching for all non-moving geometry. Mark objects as "Static" in the Inspector. Unity will combine meshes that share materials into single draw calls at build time.

  • [ ] Enable Dynamic Batching for small, moving objects (under 300 vertices). Note that dynamic batching has CPU overhead - profile to confirm it is actually helping.

  • [ ] Use GPU Instancing for repeated objects (trees, rocks, grass, props). This was critical for Domi Online, where we needed to render dense, interactive forests. We implemented a system that rendered 10,000+ trees with GPU Instancing, swapping to interactive "Stump" prefabs only when a player interacted with a specific tree.

  • [ ] Use Sprite Atlases for 2D games. Every separate sprite texture is a potential draw call break. Pack sprites into atlases using Unity's Sprite Atlas tool.

  • [ ] Minimize material variety. Each unique material requires a separate draw call. Use texture atlases to combine multiple textures into a single material where possible.

  • [ ] Use the SRP Batcher (if using URP or HDRP). The Scriptable Render Pipeline Batcher reduces the CPU cost of draw calls by batching shader property uploads. Ensure your shaders are SRP Batcher compatible.

  • [ ] Check the Frame Debugger. Look for draw calls that are rendering invisible objects, duplicate passes, or unnecessary post-processing effects.

Overdraw

Overdraw occurs when the GPU renders pixels that are immediately covered by other pixels. On mobile GPUs with limited fill rate, this is a serious performance drain.

  • [ ] Use the Scene View's overdraw visualization mode to identify problem areas.
  • [ ] Reduce transparent/alpha-blended objects. Particles are a common culprit - reduce particle counts and sizes.
  • [ ] Avoid overlapping UI elements with transparency. Flatten your UI hierarchy where possible.

Texture Optimization

Textures are typically the single largest contributor to both memory usage and download size. Getting texture settings right has an outsized impact on mobile performance.

The Texture Checklist

  • [ ] Use ASTC compression for both iOS and Android. ASTC is the modern standard for mobile texture compression, offering better quality-per-bit than ETC2 or PVRTC. Unity supports ASTC on both platforms.

  • [ ] Set appropriate Max Size. Does a background texture really need to be 2048x2048 on a 6-inch phone screen? In many cases, 512x512 or 1024x1024 is indistinguishable to the player and uses 75% less memory.

  • [ ] Disable Read/Write Enabled on textures that do not need CPU access. When enabled, Unity keeps a copy of the texture in CPU memory in addition to GPU memory - doubling the memory cost.

  • [ ] Use mipmaps for 3D textures. Mipmaps slightly increase memory usage (by ~33%) but dramatically improve rendering performance and visual quality for objects at varying distances. Disable mipmaps only for UI textures and sprites that are always rendered at the same size.

  • [ ] Use Power-of-Two dimensions. Non-power-of-two (NPOT) textures cannot be compressed on many mobile GPUs and may be padded to the next power of two anyway, wasting memory.

  • [ ] Audit texture memory. Use the Memory Profiler to see exactly how much memory each texture consumes. Sort by size and question whether the largest textures justify their resolution.


Memory Management and Garbage Collection

Garbage collection (GC) spikes are the most common cause of stuttering in Unity mobile games. When the managed heap fills up, the Mono or IL2CPP runtime pauses the game to clean up unused allocations. On mobile hardware, these pauses are longer and more noticeable.

The Memory Checklist

  • [ ] Eliminate per-frame allocations. Use the Profiler's GC Alloc column to identify scripts that allocate memory every frame. Common offenders: string concatenation, LINQ queries, foreach on certain collection types, boxing value types, and GetComponent<T>() calls.

  • [ ] Cache component references. Call GetComponent<T>() in Awake() or Start() and store the result. Never call it in Update().

  • [ ] Use object pooling. Instead of instantiating and destroying objects (bullets, particles, enemies), maintain a pool of pre-instantiated objects and recycle them. This eliminates both instantiation cost and GC pressure.

  • [ ] Pre-allocate collections. If you know a List<T> will hold 100 items, initialize it with new List<T>(100) to avoid repeated internal array resizing.

  • [ ] Use StringBuilder for any string operations in hot paths. String concatenation with + creates a new string object every time.

  • [ ] Avoid closures and lambdas in hot paths. They generate hidden allocations. Use method references or pre-allocated delegates instead.

  • [ ] Use IL2CPP, not Mono. IL2CPP compiles C# to C++ ahead of time, producing faster code with better memory characteristics. It is required for iOS and strongly recommended for Android.

Key Takeaway: Every allocation in a frame-sensitive path is a future GC spike. The goal is zero allocations per frame in your core game loop. Use the Unity Profiler's GC Alloc column as your scorecard.


Shader Optimization

Shaders are often overlooked during optimization because their performance impact is not immediately visible in the CPU profiler. But on mobile GPUs, complex fragment shaders and unnecessary passes can halve your frame rate.

The Shader Checklist

  • [ ] Use URP (Universal Render Pipeline). URP is designed for mobile and mid-range hardware. It is significantly more efficient than the Built-in Render Pipeline for mobile targets.

  • [ ] Use the Lit shader sparingly. The URP Lit shader is versatile but expensive. For objects that do not need dynamic lighting (UI elements, skyboxes, distant terrain), use Unlit or Simple Lit shaders.

  • [ ] Minimize shader variants. Every keyword combination generates a separate shader variant. Disable unused features (emission, detail maps, specular highlights) in your materials to reduce variant count and build time.

  • [ ] Avoid complex fragment operations. Per-pixel calculations like real-time shadows, multiple light sources, and complex normal mapping are expensive on mobile GPUs. Use baked lighting where possible.

  • [ ] Bake lighting. For static environments, baked lightmaps provide beautiful lighting at nearly zero runtime GPU cost. Use Light Probes for dynamic objects moving through baked scenes.

  • [ ] Reduce real-time shadow usage. Real-time shadows are one of the most expensive rendering features on mobile. Consider blob shadows, projected shadows, or baked shadow maps as cheaper alternatives.


Physics and Update Loops

Physics calculations and inefficient update loops are common CPU bottlenecks, especially in games with many active objects.

The Physics Checklist

  • [ ] Reduce Fixed Timestep frequency. The default fixedDeltaTime of 0.02 (50 physics updates per second) may be unnecessary for your game. For turn-based or slower-paced games, 0.04 (25Hz) or even lower can save significant CPU time.

  • [ ] Use simplified collision meshes. Never use Mesh Colliders on complex models. Use primitive colliders (Box, Sphere, Capsule) or simplified convex meshes.

  • [ ] Disable unnecessary Rigidbodies. Objects that do not need physics simulation should not have Rigidbody components.

  • [ ] Use layer-based collision matrix. In Project Settings > Physics, disable collision checking between layers that should never interact. This prevents the physics engine from wasting time on impossible collisions.

The Script Checklist

  • [ ] Avoid empty Update() and FixedUpdate() methods. Unity calls these every frame even if they are empty. Remove them from any MonoBehaviour that does not use them.

  • [ ] Use coroutines or timers for periodic checks. If you only need to check something every 0.5 seconds, do not check it every frame. Use InvokeRepeating, coroutines with WaitForSeconds, or a manual timer.

  • [ ] Minimize FindObjectOfType and similar searches. These scan the entire scene hierarchy. Cache references at startup or use event-driven patterns.


Frame Rate Strategy

Not every game needs 60fps. Choosing the right target frame rate is a critical optimization decision that affects battery life, thermal performance, and development complexity.

30fps vs 60fps

  • 60fps - Required for action games, competitive multiplayer, and any game where input responsiveness is critical. Demands aggressive optimization across all systems.
  • 30fps - Acceptable for turn-based strategy, puzzles, narrative games, and educational titles. Halves the rendering budget, dramatically reduces heat generation, and extends battery life.

Adaptive Frame Rate

For games that have both intense and calm moments, consider an adaptive frame rate strategy:

  • Run at 60fps during combat or action sequences.
  • Drop to 30fps during menus, inventory screens, and idle states.
  • Monitor device temperature and reduce the target if the phone is throttling.

Unity's Application.targetFrameRate makes this straightforward to implement. Use it alongside QualitySettings to adjust visual fidelity based on device capability.

Tier-Based Quality Settings

Not all phones are equal. We implement a device tier system on most of our mobile development projects:

  • High tier (flagship devices) - Full resolution, 60fps, high-quality shadows, post-processing.
  • Mid tier (2-3 year old devices) - Reduced resolution, 30fps, simplified shadows, minimal post-processing.
  • Low tier (budget devices) - Further reduced resolution, 30fps, no real-time shadows, no post-processing.

Detect the device at startup using SystemInfo.graphicsDeviceName, available RAM, and processor core count, then automatically select the appropriate quality tier.


The Build and Deployment Checklist

Before shipping any mobile build, verify these settings:

  • [ ] Scripting Backend: IL2CPP (not Mono). Better performance, required for iOS, and provides a layer of code obfuscation.
  • [ ] Strip Engine Code: Enabled. Removes unused Unity modules from the build, reducing file size.
  • [ ] Managed Stripping Level: Medium or High. Strips unused managed code. Test thoroughly, as aggressive stripping can remove code accessed only via reflection.
  • [ ] Target Architecture: ARM64. 32-bit support is no longer required by iOS and is being phased out on Android.
  • [ ] Graphics API: Vulkan (Android), Metal (iOS). These modern APIs provide better performance than OpenGL ES.
  • [ ] Texture Compression: ASTC. As discussed above. Verify in Build Settings per platform.
  • [ ] Remove debug logging. Debug.Log() calls have measurable overhead on mobile. Use conditional compilation (#if UNITY_EDITOR) or strip them entirely for release builds.

Putting It All Together

Optimization is iterative. Profile, identify the biggest bottleneck, fix it, and profile again. Resist the temptation to optimize everything at once - focus on the changes that yield the largest measurable improvement.

The order of priority we follow on most mobile projects:

  1. Profile on real hardware to identify the actual bottleneck.
  2. Reduce draw calls through batching, instancing, and material consolidation.
  3. Optimize textures for mobile compression and appropriate resolution.
  4. Eliminate GC allocations in the game loop.
  5. Simplify shaders and lighting for mobile GPU constraints.
  6. Tune physics and script frequency to reduce CPU load.
  7. Set appropriate frame rate targets with tier-based quality settings.
  8. Verify build settings before every release.

If your Unity mobile project is struggling with performance and you need expert help, our performance optimization team can audit your project, identify the critical bottlenecks, and implement targeted fixes. We bring the same rigour we applied to RuneScape Mobile and Domi Online to every engagement.


Related Reading