Voltar para o Blog
Quest Log

Reduzir o Tamanho da Build na Unity (APK e PC)

Caixa de jogo sendo comprimida por uma prensa, com blocos de textura e ondas de áudio saindo pelas laterais

Unity build size sob controle: leia o Build Report, ajuste texturas, áudio, stripping e IL2CPP e encolha APK, AAB e build de PC sem quebrar o jogo.

Ferramenta:Unity

Reduzir o Tamanho da Build na Unity (APK e PC)

Para reduzir o unity build size, o primeiro passo não é mexer em configuração: é abrir o Build Report e descobrir o que está ocupando espaço. Na maioria dos projetos pequenos, três ou quatro texturas e uns arquivos de áudio respondem pela maior parte do APK, e o resto é ruído. Aqui você mede, ataca na ordem certa (texturas, áudio, código, Resources, Android) e sai com um script de Editor que lista os maiores assets da última build.

Tudo aqui vale para o Unity 6.3 LTS. Os nomes de menu e opções foram conferidos na documentação oficial em outubro de 2026.

Medir: o que está ocupando espaço

Antes de baixar a qualidade de tudo no chute, faça uma build de release do jeito que você vai publicar (mesma plataforma, mesmo backend de script). Anote o tamanho do arquivo final: o .apk ou .aab no Android, a pasta inteira no PC (o executável sozinho engana, o peso está na pasta _Data).

Duas regras de medição que evitam trabalho jogado fora:

  • Compare builds equivalentes. Development Build liga símbolos e conexões de profiler e muda o tamanho. Compare release com release.
  • Mude uma coisa por vez. Se você muda compressão de textura e stripping na mesma build e algo quebra, não sabe qual dos dois foi.

A própria documentação da Unity diz que formato de origem não importa: um .psd com camadas e um .png exportado dele viram o mesmo dado na build, porque a Unity reimporta e recomprime tudo. Converter seus arquivos de origem não economiza nada. O que economiza está nas configurações de importação.

Unity build size: ler o Build Report

Depois de qualquer build, a Unity escreve um resumo no Editor Log. Para abrir: Window > General > Console, clique no menu de três pontos da janela Console e escolha Open Editor Log. Procure pelo trecho que começa com Build Report. Ele traz duas partes:

  1. Um resumo por categoria (Textures, Meshes, Animations, Sounds, Shaders, Other Assets, Levels, Scripts, Included DLLs, File headers) com o tamanho e a porcentagem de cada uma.
  2. A lista de assets usados, do maior para o menor.

A primeira parte diz onde atacar. Se Textures está em 70%, não adianta passar uma tarde ajustando stripping de código. A segunda parte diz qual arquivo. É comum encontrar uma imagem de fundo de 4096x4096 usada numa tela de menu que nunca passa de 1080 pixels de altura.

Um detalhe que a doc da Unity destaca: se "File headers" estiver alto, desconfie da pasta Resources cheia de coisa grande.

Build Report Inspector e um script próprio

O arquivo completo do relatório fica em Library/LastBuild.buildreport. A Unity mantém o pacote Build Report Inspector (com.unity.build-report-inspector) para ver esse arquivo no Inspector, mas ele está em versão preview (0.3). Se quiser usar, instale pelo Package Manager com Add package by name e o nome do pacote. Como é preview, não conte com ele em toda versão.

Uma alternativa estável é ler o relatório você mesmo pela API BuildReport, que existe no Unity 6.3. Crie o arquivo Assets/Editor/BuildSizeReport.cs (a pasta precisa se chamar Editor para o script não entrar na build):

using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEditor.Build.Reporting;
using UnityEngine;

public static class BuildSizeReport
{
    private const int TopCount = 30;

    [MenuItem("Tools/Build Size/Maiores assets da ultima build")]
    private static void PrintLargestAssets()
    {
        BuildReport report = BuildReport.GetLatestReport();
        if (report == null)
        {
            Debug.LogWarning("Nenhum Build Report encontrado. Faça uma build primeiro.");
            return;
        }

        Dictionary<string, ulong> sizeByAsset = new Dictionary<string, ulong>();

        foreach (PackedAssets packed in report.packedAssets)
        {
            foreach (PackedAssetInfo info in packed.contents)
            {
                string path = string.IsNullOrEmpty(info.sourceAssetPath)
                    ? "(gerado pela Unity)"
                    : info.sourceAssetPath;

                sizeByAsset.TryGetValue(path, out ulong current);
                sizeByAsset[path] = current + info.packedSize;
            }
        }

        StringBuilder sb = new StringBuilder();
        sb.AppendLine($"Build total: {ToMegabytes(report.summary.totalSize):F2} MB");
        sb.AppendLine($"Top {TopCount} assets por tamanho empacotado:");

        foreach (KeyValuePair<string, ulong> entry in sizeByAsset.OrderByDescending(e => e.Value).Take(TopCount))
        {
            sb.AppendLine($"{ToMegabytes(entry.Value),8:F2} MB  {entry.Key}");
        }

        Debug.Log(sb.ToString());
    }

    private static double ToMegabytes(ulong bytes)
    {
        return bytes / (1024.0 * 1024.0);
    }
}

Depois de uma build, rode Tools > Build Size > Maiores assets da ultima build e a lista aparece no Console. A vantagem sobre o Editor Log é que você controla o formato e pode, por exemplo, filtrar só o que vem de Assets/Art. Esse relatório mostra os dados serializados dos assets; o tamanho do código nativo (IL2CPP) não entra nele, por isso o total da lista é menor que o arquivo final.

Texturas: Max Size e compressão

Texturas são a primeira suspeita em quase todo projeto. Selecione a textura e olhe o painel de importação, na parte de baixo do Inspector, com as abas Default e por plataforma:

  • Max Size: limita a dimensão importada. Uma arte de 4096 que aparece com 512 pixels na tela pode cair para 1024 ou 512 sem diferença visível. Esse é o ajuste com maior retorno.
  • Format e Compression: deixe em formato comprimido. None (sem compressão) multiplica o tamanho.
  • Use Crunch Compression: só disponível com Format em Automatic. Reduz bastante o tamanho em disco ao custo de tempo de importação maior. O Compressor Quality controla o equilíbrio entre qualidade e tamanho.
  • Generate Mipmaps: em sprite de jogo 2D e em UI, normalmente pode desligar. Mipmap acrescenta cerca de um terço ao tamanho da textura.

Use a aba da plataforma (o ícone do Android, por exemplo) para baixar o Max Size só no celular e manter qualidade cheia no PC.

Para pixel art, mantenha Filter Mode em Point e Compression em None ou em um formato sem perda visível: compressão com bloco borra pixels. Como pixel art usa texturas pequenas, o custo fica baixo. Agrupar sprites num Sprite Atlas também ajuda, porque evita sobra de espaço entre texturas soltas.

Áudio: Load Type e qualidade

O segundo vilão é áudio importado sem cuidado. No Inspector do AudioClip:

  • Compression Format: PCM é sem compressão e enorme. Use Vorbis/MP3 para música e falas longas, ADPCM para efeitos curtos que tocam muito (passo, tiro).
  • Quality: o slider vale para formatos comprimidos. Música de fundo costuma soar bem bem abaixo de 100.
  • Force To Mono: efeitos sonoros raramente precisam de estéreo. Marcar isso corta o tamanho pela metade.
  • Sample Rate Setting: Optimize Sample Rate ou Override Sample Rate para 22050 Hz em efeitos simples.
  • Load Type: afeta mais memória do que tamanho em disco. Streaming para música longa, Decompress On Load para efeitos curtos.

Uma trilha de 3 minutos em PCM estéreo ocupa dezenas de megabytes. A mesma trilha em Vorbis com qualidade média ocupa uma fração disso.

Resources e assets não usados

A Unity só coloca na build o que é referenciado por cena ou por outro asset, com uma exceção grande: tudo que está em qualquer pasta chamada Resources entra inteiro, usado ou não. É o lugar onde os megabytes esquecidos se escondem: o pacote de teste que você importou da Asset Store, a pasta de música que nunca foi usada.

Para limpar:

  1. Busque no Project por pastas Resources (digite Resources na busca do Project e filtre por pasta).
  2. Mova para fora delas tudo o que não é carregado por Resources.Load.
  3. Para o que precisa ser carregado sob demanda, considere Addressables, que deixam você baixar conteúdo depois da instalação. O post sobre Addressables na Unity mostra a configuração.

Cenas fora da lista de build não entram, mas assets referenciados por um prefab que está em Resources entram junto. Siga a cadeia.

Ajustar build é a parte chata que aparece no fim do projeto, quando você já juntou movimento, animação, UI e áudio e descobre que nada foi pensado para caber num celular. É nesse momento que muito projeto solo para. No curso de Unity a gente monta o jogo inteiro com essas decisões tomadas desde o começo (importação de textura, áudio, organização de pastas), para a build final não virar uma faxina de uma semana.

Curso de Unity
Quer fazer seu primeiro jogo na Unity?

No curso de Unity 6 da CursoGame.Dev você vai do zero ao primeiro jogo, com um desafio prático em cada level e suporte individual no WhatsApp quando travar.

Conhecer o curso de Unity
Suporte no WhatsAppAcesso vitalícioGarantia de 7 dias

Code stripping e IL2CPP

Em Edit > Project Settings > Player > Other Settings, seção Optimization, fica o Managed Stripping Level. As opções no Unity 6.3 são Disabled, Minimal, Low, Medium e High. O padrão com IL2CPP é Minimal, e a doc marca Low para descontinuação futura e recomenda Minimal ou Medium.

  • Minimal: tira bibliotecas de classe e partes da UnityEngine que não são usadas. Seguro.
  • Medium: roda o UnityLinker com análise mais agressiva. Bom ganho, pode exigir link.xml.
  • High: remove o máximo possível. Maior risco de quebrar código chamado por reflection.

O Scripting Backend (Mono ou IL2CPP) fica na mesma tela. No Android, ARM64 só existe com IL2CPP, então para publicar na Google Play você vai usar IL2CPP de qualquer jeito. No PC, Mono gera build mais rápida de compilar e IL2CPP costuma rodar melhor; teste os dois se o tamanho for crítico.

Mais uma: em Api Compatibility Level, .NET Standard limita você a um subconjunto menor da API .NET, e a doc da Unity cita isso como fator de tamanho.

Android: AAB e ABIs

No Android, duas decisões mudam o que o jogador baixa:

Build App Bundle (Google Play): fica na tela de build (Build Profiles), não no Player Settings. Com AAB, você envia um pacote único e a Google Play monta o APK específico para cada aparelho, só com a arquitetura daquele celular. O jogador baixa menos sem você fazer nada além de marcar a opção. A Google Play impõe limites ao tamanho de download comprimido do módulo base e dos asset packs; os números aparecem na página de ajuda do Play Console sobre limites de tamanho, e vale conferir lá na hora de publicar, porque é ela que o Play Console aplica no upload. Se o jogo passa do limite do módulo base, a opção Split Application Binary (em Publishing Settings) gera um AAB com módulo base mais asset packs.

Target Architectures: em Player Settings > Other Settings. Marque ARM64 (obrigatório na Google Play) e só mantenha ARMv7 se você quer suportar aparelhos 32 bits antigos. Cada arquitetura extra é mais uma cópia do código nativo. Se você distribui APK fora da loja (itch.io, por exemplo), Split APKs by target architecture gera um APK por arquitetura em vez de um APK gordo com todas.

O Player Settings do Android também tem Warn about App Bundle size com um limite em MB que você define. Deixe ligado: é um alarme barato.

Para o resto da otimização em celular (draw calls, memória, aquecimento), veja o guia de otimização para jogos mobile.

Erros comuns: stripping quebrando reflection

O erro clássico depois de subir o Managed Stripping Level: o jogo roda perfeito no Editor e a build quebra com MissingMethodException ou um JSON que deserializa vazio. O linker removeu um construtor ou tipo que só é chamado por reflection.

A correção é dizer ao linker o que preservar. Crie Assets/link.xml:

<linker>
  <assembly fullname="Assembly-CSharp">
    <type fullname="MeuJogo.Save.SaveData" preserve="all"/>
  </assembly>
</linker>

Ou marque a classe no código com o atributo [UnityEngine.Scripting.Preserve]. Faça um teste de build depois de cada mudança de stripping, rodando o fluxo inteiro do jogo (salvar, carregar, trocar de cena), não só a primeira tela.

Outros erros que aparecem muito:

  • Baixar Max Size de sprite de pixel art e reclamar que ficou borrado: o redimensionamento bilinear estraga pixel art. Ajuste o tamanho no arquivo de origem.
  • Esquecer da aba de plataforma: você mexe na aba Default, mas o Android tem override com outro valor, e nada muda.
  • Medir o executável do PC: o .exe é minúsculo; o peso está na pasta de dados.
  • Development Build na loja: além de maior, expõe informações que não deveriam ir para o jogador.

Próximo passo

Faça agora uma build de release, abra o Editor Log e anote as 10 maiores entradas. Ataque só as três primeiras (provavelmente texturas e áudio) e meça de novo. Em seguida, passe para desempenho em tempo de execução com o guia de otimização para 60 FPS, porque um jogo leve que engasga continua sendo um problema.

Perguntas frequentes

Por que meu APK da Unity está tão grande?

Quase sempre por causa de texturas grandes sem compressão, áudio importado como PCM e assets esquecidos na pasta Resources, que entram na build inteiros mesmo sem uso. Código raramente é o vilão. Abra o Editor Log depois da build e veja a lista de assets do maior para o menor antes de mudar qualquer configuração.

Onde fica o Build Report da Unity?

O resumo em texto fica no Editor Log: na janela Console, abra o menu de três pontos e escolha Open Editor Log, depois procure o bloco Build Report. O arquivo completo é salvo em Library/LastBuild.buildreport e pode ser lido pelo pacote Build Report Inspector ou pela API BuildReport.GetLatestReport em um script de Editor.

IL2CPP deixa a build maior ou menor que Mono?

Depende do caso. IL2CPP gera código nativo e costuma ocupar mais espaço por arquitetura, mas permite stripping mais agressivo e é obrigatório para ARM64 no Android. Para Android publicado na Google Play, IL2CPP com AAB é o caminho padrão, e o próprio AAB faz a loja entregar só a arquitetura do aparelho.

Managed Stripping Level High pode quebrar meu jogo?

Pode. Os níveis Medium e High removem código que o linker acha que ninguém usa, e código chamado por reflection (alguns serializadores JSON, injeção de dependência) parece não usado para ele. A correção é preservar esses tipos com um arquivo link.xml ou com o atributo Preserve, e testar a build final, não só o Play Mode.