
Esta é a segunda parte da história (misturada com a história dos meus erros e suas soluções) sobre como eu (por cerca de dois anos no meu tempo livre) desenvolvi um aplicativo móvel (para iOS / Android) que motivaria minha filha a resolver exemplos de matemática. Como resultado, descobriu-se um aplicativo que permite que uma criança ganhe dinheiro com sua mente.
Leia a primeira parte aqui .
Plano da parte dois
- Sobre como escrever código
- Sobre o controle de versão
- Sobre dublagem
- Sobre o ícone
- Sobre a compilação para Android e sobre o tamanho
- Sobre a construção para iOS e sobre o tamanho
- Sobre o título e a promoção
- Estatísticas
- Do que me arrependo
- O que entendeu
- Referências
Curiosidades na programação que facilita minha vida
- Desde Mono, continuo usando // TODO (nos comentários) para marcar lugares que precisam ser finalizados. Em seguida, todos esses locais podem ser convenientemente monitorados na guia Lista de tarefas (Ctrl + \, T é chamado):

- Recentemente, comecei a usar um recurso como #region , por exemplo, para ocultar áreas de enumeração de variáveis:

- é conveniente quebrar parte do código com algumas construções usando a sequência de teclas de atalho Ctrl + K, Ctrl + S. Por exemplo, seleciono a parte do código que precisa ser inserida no if e pressione Ctrl + K e, em seguida, pressione Ctrl + S, digite o nome do operador (se) necessário e pressione Enter.
- simplifica bastante o trabalho com código se você aderir a um estilo único, por exemplo, como aqui - o Guia de Estilo C # com Unity em mente .
- Estou muito feliz por ter me tornado amigo de Coroutine - essas são, grosso modo, funções que expandem sua execução em vários quadros. I.e. eles não tentam concluir nenhuma tarefa em um quadro (calculando-o por meio segundo, reduzindo o desempenho para 2 FPS), mas fazem um pouco no primeiro quadro, um pouco no segundo e assim por diante, para que o jogo não desacelere. Seu outro objetivo é executar algo que não precisa ser feito diretamente em cada quadro (por exemplo, verifique algo 3 vezes por segundo).
O exemplo abaixo mostra a corotina de um semáforo que, infinitamente (a cada dez segundos), acende uma luz amarela, vermelha e verde:
IEnumerator TrafficLights() { while (true) { yield return new WaitForSeconds(10f); yield StartCoroutine(this.GetComponent<Lamp>().BlinkYellow()); yield StartCoroutine(this.GetComponent<Lamp>().BlinkRed()); yield StartCoroutine(this.GetComponent<Lamp>().BlinkGreen()); } }
Se na linguagem humana, a instrução yield apenas diz ao Unity que é necessário transferir a execução da função para o próximo quadro (quantas vezes for necessário) até que seja executada e, em seguida, prossiga para a próxima instrução de rendimento. T.O. Os TrafficLights da Coroutine serão executados assim:
- primeiro, há uma espera de 10 segundos (primeiro rendimento),
- depois, a corotina BlinkYellow é iniciada (segundo rendimento) e até terminar, a corotina BlinkRed não é iniciada,
- Após a conclusão do BlinkYellow, o BlinkRed é lançado,
- Após a conclusão do BlinkRed, o BlinkGreen é lançado,
- então o ciclo se repete desde o início (ver ponto 1).
Controle de versão, bem, apenas realmente necessário!
O vídeo que me ajudou a começar a usar o GitHub em conjunto com o Unity - Como usar o GitHub com o Unity .
Apesar de eu mesmo (sozinho, sem equipe) escrever o código, percebi que o controle de versão do código é simplesmente vital para mim:
- Parei de ter medo de fazer alterações importantes no código que poderiam arruinar o projeto.
- É muito fácil retornar à sua condição de trabalho anterior.
- É conveniente comparar arquivos com código.
- Você pode ver claramente o que mudou no código.
- Não importa o que aconteça com o meu computador, eu sempre tenho uma versão de backup na nuvem.
Mas somente ao trabalhar com controle de versão, você precisa se acostumar a confirmar (postar atualizações) em porções muito pequenas. Para não ser como o meu, troquei 20 arquivos, adicionei uma tonelada de novas funcionalidades e fiz tudo de uma vez sob o nome "Fuh, agora finalmente funciona".
É bom que eu tenha descoberto que é melhor não adicionar arquivos de cache (pasta Library), arquivos temporários (pasta tmp, obj) ao repositório e tudo o que o Unity gera em tempo real. De fato, apenas as pastas Assets e ProjectSettings precisavam ser adicionadas ao repositório.
Não é necessário usar o GitHub, porque seu ponto negativo é que, em uma conta gratuita, é impossível tornar o código privado (visível apenas para você). Mas há GitLab ou Bitbucket , sempre que possível.
Como eu prprrrruk no microfone
Entendo minha inscrição como educacional e tento, se possível, não usar distrações. Portanto, às vezes os usuários reclamam, por exemplo, da falta de música ou de uma interface muito simples (embora uma interface simples não seja porque eu queria tanto, mas porque não sei como fazê-lo melhor). Com a música, estou um pouco em uma encruzilhada agora: quero acrescentar e cutucar (é improvável que os professores aprove a decisão de fazer um dever de matemática para a música).
Música, música, mas sem dublagem é impossível. No começo, procurei os sons de que precisava entre os livres, mas depois percebi que leva mais tempo para pesquisar do que se eu mesmo os tivesse produzido. Portanto, simplesmente criei a maioria dos sons com a boca em um microfone de telefone e os processei usando o Audacity (um software gratuito de várias plataformas para gravação e edição de áudio que eu costumava converter som de um formato para outro).
Na maioria das vezes, a lógica para criar um efeito sonoro no Audacity era a seguinte:
- Corte tudo desnecessário.
- Utilizou o efeito Redução de ruído (para remover o ruído da gravação).
- Adicionado o som do efeito de desenho animado Wahwah.
- Com efeitos, Bass e Treble foram tocados com frequências para que o som soasse mais agradável nos alto-falantes dos smartphones.
- Se eu dissesse alguma coisa, os efeitos do Change Pitch, Speed e Tempo mudavam o som da minha voz para esquilos.
No início, meu som ficou significativamente atrás do evento (não no editor, mas no smartphone). A opção Tamanho do buffer do DSP definida como Melhor latência (Editar -> Configurações do projeto -> Áudio) ajudou e estas são as dicas (tanto na pergunta quanto na resposta).
Como a filha gerou idéias de ícones
Enquanto desenvolvia o aplicativo, tentei várias vezes criar os ícones pessoalmente, mas nenhum deles se enraizou (e, na verdade, algum tipo de resíduo surgiu). Portanto, quando se tratava de uma publicação aberta, confiei o desenvolvimento de um ícone para minha filha. Expliquei a ela que o ícone deveria ser atraente e explica o significado do aplicativo. Ela surgiu com grande entusiasmo e instantaneamente desenhou uma imagem completamente inadequada. Eu o rejeitei e expliquei o que exatamente precisa ser aprimorado ou não ser usado. Então tudo correu como esperado - ela ficou ofendida e parou de desenhar ícones.
Após meio mês, o insulto passou e ela abordou a tarefa mais detalhadamente: cortou quadrados do caderno na caixa (o tamanho do ícone na tela do iPod) e começou a desenhar opções uma a uma:

Me trouxe. Eu escolhi as idéias de que gostei. Ele disse em que direção seguir em frente. Ela foi desenhar as seguintes opções. Após dois dias e três dezenas de opções, nos instalamos no canto inferior direito (foto acima).
Depois, pedi à minha filha para desenhar uma versão ampliada do ícone (a primeira à esquerda na figura abaixo), que eu digitalizei (a segunda à esquerda) e ... liguei para um amigo do artista para me ajudar na seleção de cores. Como resultado, uma versão central foi obtida. Então comecei a moer gradualmente o ícone (o segundo à direita) durante toda a vida útil do aplicativo nas lojas. E agora ela se parece com a extrema direita:

Android build
Este vídeo do Unity Android Build - Como me ajudou na criação do meu primeiro arquivo APK, que mostra como configurar tudo sem instalar o pesado Android Studio.
Repito que não tenho dispositivos com Android (peço aos meus amigos que testem após a nova compilação) e, portanto, não tive nenhum erro nos dispositivos mostrados no vídeo.
Mas sem problemas, ele ainda não poderia. Eu tive que mexer na atualização do SDK do Android por um longo tempo, porque o Unity não queria trabalhar com as atualizações mais recentes. Como resultado, verificou-se que era necessário permitir que o Unity escolhesse e instalasse a versão necessária da atualização em si. I.e. Acabei de clicar no botão Atualizar Android SDK no próprio Unity e não tentei atualizar tudo sozinho, como mostra o vídeo.
Problema ao atualizar o SDK do Android manualmenteAté que percebi que precisava atualizar no Unity, sofri por um longo tempo, atualizando manualmente usando o script sdkmanager.bat (você precisa usar esse script com o parâmetro --update, e não android.bat, que é indicado no vídeo). Durante a atualização, ele reclamou que não podia sobrescrever a pasta tools (a partir da qual ele próprio começou). Tentei várias dicas e nem me lembro o que ajudou, parece ser algum tipo de solução com links simbólicos.
Além disso, erros incompreensíveis relacionados ao java apareceram. Verificou-se que havia um problema com a versão do Java Development Kit - ele também não precisava ser instalado com a versão mais recente. Eu tentei vários antigos e em um deles os erros desapareceram e tudo funcionou.
Com o apk de assinatura para publicação no Google Play, o vídeo Como assinar um aplicativo Unity para o Android Market me ajudou. Salvei e salvei cuidadosamente essas duas senhas, porque elas precisam ser inseridas toda vez que você cria uma nova compilação. E se você os perder, não poderá atualizar o aplicativo (basta lançar um novo com novas chaves).
O ícone, diferente da versão do iOS, deve ser feito inicialmente com cantos arredondados; caso contrário, em alguns dispositivos, ele permanecerá perfeitamente quadrado.
Tamanho da compilação para Android
Agora, o tamanho do meu arquivo apk é 22MB.
Reduzi bem o tamanho da montagem com o formato de compactação com textura / sprite com perdas - RGBA Crunched ETC2 (para sprites com alfa) e RGB Crunched ETC (para texturas sem alfa). O principal era definir Qualidade do Compressor = 100 (este parâmetro não afeta a velocidade das texturas no dispositivo final, mas apenas a qualidade da textura e a velocidade de compactação no editor).
Quaisquer outras danças com pandeiros não me permitiram obter uma redução significativa no tamanho do arquivo apk (exceto algumas nuances descritas abaixo).
Agora estou usando o seguinte ..
.. configurações de Configurações do player ..
.. para o tamanho mínimo, por um lado, e a cobertura máxima de dispositivos, por outro:
- Unity 2018.1 (quanto mais nova a versão, melhor ela compacta e mais todas as guloseimas).
- API de gráficos automáticos (o próprio Unity escolhe OpenGLES2 e 3).
- Back-end de script - Mono (pode não ser mais rápido que o IL2CPP, mas o assembly é definitivamente menor).
- Arquiteturas de destino - ARMv7 e x86. Ao remover o suporte Intel x86, reduzi o tamanho do apk em mais 10 MB (seria 12MB). Mas não sei quantos dispositivos cortei removendo esta marca de seleção. O que eu sei é que os telefones não foram lançados há dois anos sob essa arquitetura. E os que foram encontrados podem ser contados com os dedos de uma mão (os últimos que eu sei são o Asus Zenfone, o Lenovo K 900, o Xolo x1000 e ainda pode haver alguns). Por favor, corrija-me nos comentários se estiver falando bobagem.
- Nível de agitação - montagens de tira - corta com segurança códigos desnecessários. Outras opções podem gerar algum ganho de tamanho (não reparei em casa), mas não são tão seguras.
- Build System - Gradle (permite ativar a opção Minify).
- Minify - Proguard - reduz os nomes de todas as classes e variáveis para economizar bytes miseráveis de tamanho, mas, como um bônus, torna o código menos legível para impedir a engenharia reversa.
Construção do IOS
Coleciono um aplicativo no macbook da minha esposa (lembro que eles usaram o MacBook Air mais barato de 2015).
Para criar para o iOS 7, mesmo no Xcode versão 9.3, bastava direcionar manualmente o valor 7.0 para o campo Destino de Implantação (na guia Geral ).
Para adicionar idiomas (nos quais traduzi o aplicativo usando Localização Lean) à descrição do aplicativo na AppStore, tivemos que adicionar as seguintes linhas ao arquivo info.plist (em qualquer lugar, por exemplo, imediatamente após <dict>):
<key>CFBundleLocalizations</key> <array> <string>English</string> <string>Russian</string> </array>
Agora estou usando o Unity 2017.4 para criar para iOS (como escrevi acima, preciso do suporte ao iOS 7, caso contrário, usaria 2018.1).
Tamanho de compilação do IOS
Agora, o tamanho do arquivo baixado para o meu iPhone é 44 MB.
Infelizmente, no iOS, não posso usar sprites Crunched, porque eles não são compatíveis com dispositivos anteriores ao iPhone 5s ( sem suporte para Metal e OpenGL ES 3.0 ).
Quando tentei reduzir o tamanho da compilação a qualquer custo, o menor tamanho (34 MB) foi obtido se:
- use o Unity 2018 (ou seja, a versão mínima suportada é o iOS 8),
- A API de gráficos seleciona apenas Metal,
- deixe apenas as arquiteturas de destino x64,
- use texturas trituradas.
Mas ainda não descobri como trabalhar com o afinamento de aplicativos - isso permite que a loja de aplicativos monte automaticamente meu aplicativo para um iPhone / iPad / iPod específico do usuário final (o que leva a uma diminuição no tamanho do arquivo baixado). Eu só tive tempo de escrever artigos nos meus favoritos:
Configurações do My Player que eu quero compartilhar:
- É conveniente inserir o ID da equipe de assinatura automática uma vez (você pode obtê-lo no site do desenvolvedor da Apple aqui Conta> Associação ) e marque a caixa Assinar automaticamente para não fazer isso todas as vezes no Xcode posteriormente.
- Defino Frequência do acelerômetro como Desativado (desativei o acelerômetro), porque não o uso. Eu posso economizar um pouco de bateria para as pessoas.
- Comportamento em segundo plano - Suspender - dessa maneira, o aplicativo não fecha quando você pressiona o botão Início, mas continua a funcionar em segundo plano (você pode capturar esse evento usando OnApplicationPause para salvar o jogo, por exemplo).
Como escolhi o nome e o que usei para promoção
Quantos usaram Booking e TripAdvisor, mas eu nunca notei que o nome na AppStore não é apenas Booking, mas “Booking.com Travel Deals” e “TripAdvisor Hotels Restaurants” (o nome é diluído em palavras-chave, para que o aplicativo se baseie nessas palavras-chave encontrado em busca de apstor). Portanto, decidi não usar o nome antigo Math4Ami, mas por muito tempo joguei com palavras diferentes para incluir as palavras-chave necessárias. No final, cheguei ao Pocket Money: Math e depois para Learn Math & Earn Pocket Money. Em russo, essas opções pareciam Pocket Money for Maths e Pocket Money and Maths: Learn and Earn.
Promovi minha inscrição enviando / publicando links para amigos e conhecidos, escrevi dois artigos no meu blog e pendurei um banner no mesmo local.
A propósito, se você colocar esta linha nas páginas da web <head>:
<meta name="apple-itunes-app" content="app-id=1372434662" />
.. então, abrindo esta página no iPhone, todos verão o banner do seu aplicativo na parte superior.
Estatísticas de download
Primeiro eu lancei a versão iOS.

Muitas pessoas falaram sobre antipatia por dispositivos Apple e convenceram que o Android é muito mais bacana. Decidi verificar e, após 20 dias de processo com a montagem do arquivo apk, fiz um lançamento no Google Play.

Você não fará conclusões objetivas (ou absolutamente nenhuma), mas puramente subjetivas - eu esperava mais da plataforma do Google, mas no momento acabou sendo meio pior que a Apple.
Lamento que:
- Não fiz backups quando mudei para a nova versão do Unity
- não usou um sistema de controle de versão (como git),
- Eu tentei trabalhar com o Perforce (apenas um sistema terrível - que reduz o desenvolvimento de forma irrealista),
- nunca usei ScriptableObject (SO) antes - é tão legal
- Eu escrevi o código em uma folha longa (é assustador lembrar como refatorei esta folha mais tarde),
- Eu não sabia o que eram os cheiros de código , mas como eu precisava saber sobre eles,
- Tentei usar variáveis globais em todos os lugares, e não locais (pensando paranóico que, se eu frequentemente solicitar uma função, a variável local dentro da função será criada repetidas vezes e haveria apenas uma global. Como resultado, depois de centenas de chamadas para a função com variáveis locais, Eu teria um monte de memória desperdiçada e perda de desempenho devido ao Garbage Collector),
- Eu nem sempre segui um estilo uniforme no código e no nome de todos os ativos. Aqui está um bom exemplo para o UE4 (há muitas coisas úteis sobre como nomear ativos e eu também o uso no Unity),
- Esqueci que escrevi o aplicativo principalmente para minha filha, e não por um código bonito ou para agradar a outros usuários.
Eu percebi que:
- as crianças são muito fáceis de se sentar no meu aplicativo (imediatamente após a instalação do aplicativo, elas podem ficar suspensas por horas até que a bateria do telefone fique sem carga),
- as crianças são viciadas em matemática na minha inscrição, mesmo que não falem sobre dinheiro. Se há dois filhos na família, chegou a brigas por telefone para resolver exemplos,
- Meu aplicativo fica entediado muito rapidamente para as crianças. No dia seguinte, poucas pessoas jogaram o aplicativo, mesmo que a criança percebesse que receberia dinheiro por isso,
- a retenção deficiente de usuários / crianças não é exatamente o problema específico da minha inscrição, mas as especificidades do ensino de crianças (isso foi informado pelos professores da escola). A aplicação deve ser muito diversificada para manter o interesse das crianças o tempo todo,
- Com frequência, pais e filhos interpretam mal o princípio do aplicativo e pensam que, ao resolver exemplos, eles receberão dinheiro de mim (do desenvolvedor). Recebi cartas diferentes com perguntas como: como sacar dinheiro, posso sacar para webmoney ou paypal, onde especificar o endereço para enviar dinheiro por cheque, etc.,
- se você se desculpar por seus erros e descuidos nas respostas a críticas ruins (e também explicar como realmente deve funcionar), as pessoas tenderão a perdoar erros e remover notas ruins,
- você não vai muito longe em sua própria promoção,
- as crianças crescem muito rápido e enquanto eu escrevia o aplicativo - minha filha já o superou. Mas, meu novo "testador" está crescendo!
Referências
Lista de links do artigo na ordem em que são mencionados:
Como manter um estilo de código único Guia de Estilo C # com Unity em mente .
+ GitHub e vídeo sobre como parafusar o git no Unity .
+ Existe um repositório privado gratuito no GitLab ou Bitbucket .
+ Audacity grátis para gravar e editar áudio.
+ Como remover o atraso do som .
+ Tutorial de vídeo do Build Android da Unity - Como .
+ Vídeo Como assinar um aplicativo Unity para o Android Market .
+ Dispositivos Apple compatíveis com Metal / OpenGL ES 3 .
+ Diluição do aplicativo (documentação da Apple).
+ Desbaste de aplicativos (ajuda do Unity).
+ Fluxo de trabalho do AssetBundle (documentação do Unity).
+ Onde obter o ID da equipe .
+ O que são cheiros de código .
+ O princípio de nomear ativos / recursos em projetos de jogos no UE4 .
Obrigado pela leitura!