Unity Game Development

Our video game development company runs independent projects, jointly creates games with the client and provides additional operational services. Expertise of our team allows us to cover all gaming platforms and develop an amazing product that matches the customer’s vision and players preferences.
Showing 1 of 1 servicesAll 242 services
Unity Game Development
Complex
from 1 week to 3 months
FAQ
Our competencies
What are the stages of Game Development?
Latest works
  • image_games_mortal_motors_495_0.webp
    Game development for Mortal Motors
    670
  • image_games_a_turnbased_strategy_game_set_in_a_fantasy_setting_with_fire_and_sword_603_0.webp
    A turn-based strategy game set in a fantasy setting, With Fire and Sword
    860
  • image_games_second_team_604_0.webp
    Game development for the company Second term
    490
  • image_games_phoenix_ii_606_0.webp
    3D animation - teaser for the game Phoenix 2.
    533

Unity Game Development

The project is halfway through, scenes don't compile into builds without compiler errors, the AssetBundle cache has bloated to 4 GB, and on the target Android device URP renders at 8 FPS instead of 30. A familiar picture. Unity is a powerful tool, but with improper architecture it becomes a source of technical debt faster than you can finish the gameplay.

Where Unity projects typically break

The most common problem is improper management of object lifecycle. MonoBehaviour.Update() on 400 active objects, each pulling GetComponent<Rigidbody>() every frame — that's not architecture, that's a disaster. On PC it's unnoticed. On an iOS A14 this is 12 ms of overhead from reflection alone.

The second classic pitfall is AddressableAssets without an unload strategy. The project loads locations through Addressables.LoadAssetAsync, but forgets to call Addressables.Release(). After an hour of gameplay session, the process's RSS grows from 800 MB to 2.4 GB, and iOS kills the app. This isn't a Unity bug — it's an architecture bug.

The third pain point is mixing logic between scenes and ScriptableObjects. A team starts with MonoBehaviour singletons, then transitions to a ScriptableObject-based EventSystem, but ends up with the event system living in three places simultaneously. Every new developer adds another layer, and after six months nobody knows where OnPlayerDied comes from.

A less obvious but recurring problem: Physics.Raycast in Update() without LayerMask. Each call checks all colliders in the scene. With 50 agents and complex geometry, that's 1-2 ms per frame just on physics.

How we structure Unity projects

Architecture and stack

The foundation is dividing into three layers: GameplayCore (pure C# logic with no Unity API dependencies), UnityGlue (MonoBehaviour wrappers), and Infrastructure (services: saving, analytics, networking). This enables testing gameplay without launching the editor through NUnit + Unity Test Framework.

We choose the render pipeline based on platform:

Platform Pipeline Reason
Mobile (iOS/Android) URP Batching, SRP Batcher, low overhead
PC / Console URP or HDRP HDRP only for AAA rendering needs
WebGL URP Built-in is outdated, HDRP not supported
2D Project URP 2D Tilemap, Sprite Atlas, 2D Lighting

We write shaders through ShaderGraph where visual iteration with the artist is needed. High-performance low-level effects are written manually in HLSL with Custom Function Node. We use Amplify Shader Editor only if the project already relies on it.

Draw call optimization

On mobile projects the standard goal is no more than 100-150 draw calls per frame. Achieved through:

  • GPU Instancing on repeating geometry (trees, props). MaterialPropertyBlock for per-instance data without batch breaks.
  • SRP Batcher — works automatically with URP, but requires all shaders to be SRP-compatible. One incompatible material breaks the entire batch.
  • Sprite Atlas for UI — critical. A UI Canvas in Overlay mode with 60+ individual sprites creates 60+ draw calls just for the interface.
  • Occlusion Culling for 3D scenes — we bake through Window → Rendering → Occlusion Culling. On levels with opaque geometry, reduces draw calls by 40-60%.

We profile through Unity Profiler + Frame Debugger + RenderDoc (for detailed GPU analysis). On Android additionally — Android GPU Inspector for Mali/Adreno.

Multithreading and ECS

For projects with large agent counts or simulations we consider DOTS (Unity ECS + Burst Compiler + Jobs System). Burst compiles C# to native SIMD code — on tasks like pathfinding for 1000 agents it's the difference between 16 ms and 0.8 ms on the main thread.

For typical projects without DOTS — UniTask instead of coroutines. Coroutines run on MainThread and don't cancel correctly when the object is destroyed. UniTask with CancellationToken solves both issues.

Multiplayer

For real-time: Photon Fusion 2 (server-authoritative, rollback netcode) or Mirror (self-hosted, open source). Choice depends on latency requirements and infrastructure budget. For turn-based and asynchronous interactions — PlayFab CloudScript + Azure Functions.

Saves and cloud sync — Firebase Realtime Database for simple cases, PlayFab for full game backend (leaderboards, matchmaking, economy).

What the workflow looks like

Pre-production (1-2 weeks). We break down the specification, determine target platforms and technical constraints. We create a vertical slice — a minimally working mechanic in isolation. This is more important than a full design document: it's better to spend a week on a prototype than three months developing a mechanic that won't work on target hardware.

Production. Sprints of 1-2 weeks. Each sprint ends with a working build. We use Git with LFS for assets, Jira or Linear for tasks. Code review is mandatory — especially for systems affecting multiple scenes.

Testing. Unit tests for gameplay logic (Unity Test Framework, Play Mode). Integration tests through Playwright for WebGL. Manual testing on real devices — iOS simulator doesn't reproduce real memory consumption.

Launch. Automated builds through Unity Cloud Build or GitHub Actions with fastlane for iOS. Android — Google Play Internal Testing, iOS — TestFlight.

Timeline by project type

Project Type Scope Approximate Timeline
Hyper-casual game 1-3 mechanics, no backend 2-4 weeks
Casual mobile Progression, monetization, cloud 2-4 months
Midcore mobile Meta-gameplay, PvP, economy 4-8 months
PC indie Single-player campaign 3-9 months
PC multiplayer Networking, matchmaking, anti-cheat 6-18 months

Cost is calculated individually after analyzing the technical specification and target platforms.

Common mistakes when launching a Unity project

Ignoring Profiler until polish. "Do it first, optimize later" works until you realize an architecture decision made in month one can't be optimized without rewriting half the game.

Storing all assets in Resources/. The Resources folder loads entirely into memory on app startup. 500 MB of textures in Resources means 500 MB of RAM before the first scene launches. Addressables solve this, but require planning from the start.

One giant Canvas for all UI. Unity redraws the entire Canvas when any child element changes. Split UI into static and dynamic Canvas components.

Physics on triggers instead of calculations. OnTriggerEnter is reliable at low speeds. A bullet traveling 200 units/sec passes through thin colliders between frames. For such cases you need Physics.SphereCast or Rigidbody with Continuous Collision Detection.