
Esta es la segunda parte de la historia (mezclada con la historia de mis errores y sus soluciones) sobre cómo yo (durante unos dos años en mi tiempo libre) desarrollé una aplicación móvil (para iOS / Android) que motivaría a mi hija a resolver ejemplos matemáticos. Como resultado, resultó una aplicación que le permite a un niño ganar dinero con su mente.
Lee la primera parte aquí .
Plan de la segunda parte
- Sobre escribir código
- Sobre el control de versiones
- Sobre la actuación de voz
- Sobre el icono
- Sobre la compilación para Android y sobre el tamaño
- Sobre la compilación para iOS y sobre el tamaño
- Sobre el título y promoción
- Estadísticas
- Lo que lamento
- Lo que entendido
- Referencias
Curiosidades en la programación que me hacen la vida más fácil
- Desde Mono, sigo usando // TODO (en los comentarios) para marcar los lugares que deben finalizarse. Luego, todos estos lugares se pueden monitorear convenientemente en la pestaña Lista de tareas (se llama Ctrl + \, T):

- Recientemente, comencé a usar una función como #region , por ejemplo, para ocultar áreas de enumeración de variables:

- es conveniente envolver parte del código con algunas construcciones usando la secuencia de teclas de acceso rápido Ctrl + K, Ctrl + S. Por ejemplo, selecciono la parte del código que debe colocarse dentro del if y presiono Ctrl + K, y luego presiono inmediatamente Ctrl + S, ingreso el nombre del operador (if) que necesita y presiono Enter.
- simplifica enormemente el trabajo con el código si se adhiere a un estilo único, por ejemplo, como aquí: la Guía de estilo de C # con Unity en mente .
- Estoy muy contento de haberme hecho amigo de Coroutine; estas son, más o menos, funciones que extienden su ejecución en varios marcos. Es decir no intentan completar ninguna tarea en un cuadro (calculando durante medio segundo, reduciendo así el rendimiento a 2 FPS), pero hacen un poco en el primer cuadro, un poco en el segundo y así sucesivamente, para que el juego no se ralentice. Su otro propósito es realizar algo que no es necesario hacer directamente en cada cuadro (por ejemplo, verificar algo 3 veces por segundo).
El siguiente ejemplo muestra la rutina de un semáforo que se ilumina infinitamente (cada diez segundos) a su vez, una luz amarilla, roja y 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()); } }
Si está en lenguaje humano, la declaración de rendimiento solo le dice a Unity que es necesario transferir la ejecución de la función al siguiente cuadro (tantas veces como sea necesario) hasta que se ejecute, y luego pasar a la siguiente instrucción de rendimiento. T.O. Coroutine TrafficLights se ejecutará así:
- primero hay una espera de 10 segundos (primer rendimiento),
- entonces comienza la rutina de BlinkYellow (segundo rendimiento) y hasta que finaliza, la rutina de BlinkRed no comienza,
- al finalizar BlinkYellow, se lanza BlinkRed,
- al finalizar BlinkRed, se lanza BlinkGreen,
- entonces el ciclo se repite desde el principio (ver punto 1).
Control de versiones, bueno, ¡realmente necesario!
El video que me ayudó a comenzar a usar GitHub junto con Unity: cómo usar GitHub con Unity .
A pesar de que yo mismo (solo, sin un equipo) escribo el código, me di cuenta de que el control de la versión del código es simplemente vital para mí:
- Dejé de tener miedo de hacer cambios cardinales en el código que pudieran arruinar el proyecto.
- Es muy fácil volver a sus condiciones de trabajo anteriores.
- Es conveniente comparar archivos con código.
- Puedes ver claramente lo que ha cambiado en el código.
- No importa lo que le pase a mi computadora, siempre tengo una versión de respaldo en la nube.
Pero solo cuando trabaje con el control de versiones debe acostumbrarse a comprometerse (publicar actualizaciones) en porciones muy pequeñas. Para no ser como el mío al principio, cambié 20 archivos, agregué una tonelada de nueva funcionalidad y lo hice todo a la vez bajo el nombre "Fuh, ahora finalmente funciona".
Es bueno que una vez descubrí que es mejor no agregar archivos de caché (carpeta Biblioteca), archivos temporales (carpeta tmp, obj) al repositorio y todo lo que Unity genera sobre la marcha. De hecho, solo las carpetas Assets y ProjectSettings tuvieron que agregarse al repositorio.
No es necesario usar GitHub, porque su desventaja es que en una cuenta gratuita es imposible hacer que el código sea privado (solo visible para usted). Pero luego está GitLab o Bitbucket , donde sea posible.
¿Cómo pude usar el micrófono?
Percibo mi solicitud como educativa e intento, si es posible, no usar distracciones. Por lo tanto, a veces los usuarios se quejan, por ejemplo, de la falta de música o de una interfaz muy simple (aunque una interfaz simple no es porque la quisiera tanto, sino porque no sé cómo hacerlo mejor). Con la música, ahora estoy un poco en una encrucijada: quiero agregar y meter (es poco probable que los maestros aprueben la decisión de una tarea de matemáticas a la música).
Música, música, pero sin actuación de voz es imposible. Al principio busqué los sonidos que necesitaba entre los gratuitos, pero luego me di cuenta de que lleva más tiempo buscarlos que si los creara yo mismo. Por lo tanto, simplemente creé la mayoría de los sonidos con la boca en un micrófono telefónico y luego los procesé usando Audacity (un software gratuito multiplataforma para grabar y editar audio que solía convertir el sonido de un formato a otro).
Muy a menudo, la lógica para crear un efecto de sonido en Audacity era la siguiente:
- Cortar todo lo innecesario.
- Utiliza el efecto de reducción de ruido (para eliminar el ruido de la grabación).
- Se agregó el sonido del efecto de dibujos animados Wahwah.
- Con efectos, los graves y agudos se tocaban con frecuencias para que el sonido sonara más dulce en los altavoces de los teléfonos inteligentes.
- Si dije algo, los efectos de Change Pitch, Speed y Tempo cambiaron el sonido de mi voz a ardillas.
Al principio, mi sonido se retrasó significativamente detrás del evento (no en el editor, sino en el teléfono inteligente). La opción Tamaño de búfer DSP establecida en Mejor latencia (Editar -> Configuración del proyecto -> Audio) ayudó y estos son los consejos (tanto en la pregunta como en la respuesta).
Cómo la hija generó ideas de iconos
Mientras desarrollaba la aplicación, intenté varias veces crear los iconos yo mismo, pero ninguno de ellos echó raíces (y, en verdad, surgió algún tipo de heces). Por lo tanto, cuando se trataba de una publicación abierta, confié el desarrollo de un ícono para mi hija. Le expliqué que el ícono debería ser atractivo y explicar el significado de la aplicación. Ella surgió con gran entusiasmo e instantáneamente dibujó una imagen completamente inadecuada. Lo rechacé y le expliqué qué es exactamente lo que debe mejorarse o no utilizarse en absoluto. Luego todo salió como se esperaba: se ofendió y dejó de dibujar iconos.
Después de medio mes, el insulto pasó y ella fue a la tarea más a fondo: cortó cuadrados del cuaderno en la caja (el tamaño del icono en la pantalla de su iPod) y comenzó a dibujar las opciones una por una:

Me trajo Elegí las ideas que me gustaron. Dijo en qué dirección seguir. Ella fue a dibujar las siguientes opciones. Después de dos días y tres docenas de opciones, nos instalamos en la esquina inferior derecha (foto de arriba).
Luego le pedí a mi hija que dibujara una versión ampliada del ícono (el primero a la izquierda en la figura a continuación), que digitalicé (el segundo a la izquierda) y ... llamé a un amigo del artista para que me ayudara con la selección del color. Como resultado, se obtuvo una versión central. Luego comencé a mover gradualmente el ícono (segundo a la derecha) durante toda la vida de la aplicación en las tiendas. Y ahora se parece a la extrema derecha:

Android build
Este video de Unity Android Build: cómo me ayudó con la creación de mi primer archivo APK, que explica cómo configurar todo sin instalar el pesado Android Studio.
Repito que no tengo dispositivos con Android (solo les pido a mis amigos que prueben después de la nueva compilación) y, por lo tanto, no tuve ningún error con los dispositivos que se muestran en el video.
Pero sin problemas, todavía no podría funcionar. Tuve que jugar con la actualización del SDK de Android durante mucho tiempo, porque Unity no quería trabajar con las últimas actualizaciones. Como resultado, resultó que era necesario permitir que Unity eligiera e instalara la versión necesaria de la actualización. Es decir Acabo de hacer clic en el botón Actualizar Android SDK en Unity y no intenté actualizar todo yo mismo, como se muestra en el video.
Problema al actualizar el SDK de Android manualmenteHasta que me di cuenta de que necesitaba actualizar desde Unity, sufrí durante mucho tiempo, actualizando manualmente usando el script sdkmanager.bat (debe usar este script con el parámetro --update, y no android.bat, que se indica en el video). Durante la actualización, se quejó de que no podía sobrescribir la carpeta de herramientas (desde la cual él mismo comenzó). Probé un montón de consejos y ni siquiera recuerdo lo que ayudó, parece ser algún tipo de solución con enlaces simbólicos.
Además, aparecieron errores incomprensibles relacionados con Java. Resultó que había un problema con la versión de Java Development Kit; tampoco era necesario instalarlo con la última versión. Probé varios viejos y en uno de ellos los errores desaparecieron y todo funcionó.
Con la firma apk para publicar en Google Play, el video Cómo firmar una aplicación de Unity para el mercado de Android me ayudó. Cuidadosamente guardé y guardé estas dos contraseñas, porque deben ingresarse cada vez que crea una nueva compilación. Y si los pierde, no podrá actualizar la aplicación (solo suelte una nueva con nuevas claves).
El icono, a diferencia de la versión de iOS, debe hacerse inicialmente con esquinas redondeadas, de lo contrario, en algunos dispositivos, permanecerá perfectamente cuadrado.
Tamaño de compilación para Android
Ahora mi tamaño de archivo apk es de 22 MB.
Reduje bien el tamaño del ensamblaje con el formato de compresión de sprite / textura con pérdida: RGBA Crunched ETC2 (para sprites con alfa) y RGB Crunched ETC (para texturas sin alfa). Lo principal era establecer la calidad del compresor = 100 (este parámetro no afecta la velocidad de las texturas en el dispositivo final, sino solo la calidad de la textura y la velocidad de compresión en el editor).
Cualquier otro baile con panderetas no me permitió lograr ninguna reducción significativa en el tamaño del archivo apk (a excepción de algunos matices que se describen a continuación).
Ahora estoy usando lo siguiente ...
.. configuración de la Configuración del jugador ..
.. para el tamaño mínimo por un lado y la cobertura máxima de dispositivos por el otro:
- Unity 2018.1 (cuanto más nueva es la versión, mejor se empaca y más todas las golosinas).
- API de gráficos automáticos (la propia unidad elige OpenGLES2 y 3).
- Scripting Backend - Mono (puede que no sea más rápido que IL2CPP, pero el ensamblaje es definitivamente más pequeño).
- Arquitecturas de destino: ARMv7 y x86. Al eliminar la compatibilidad con Intel x86, reduje el tamaño del apk en otros 10 MB (sería 12 MB). Pero no sé cuántos dispositivos corté al eliminar esta marca de verificación. Lo que sé es que los teléfonos no se han lanzado desde hace dos años bajo esta arquitectura. Y los que se pueden contar con los dedos de una mano (los últimos que conozco son Asus Zenfone, Lenovo K 900, Xolo x1000 y todavía puede haber algunos). Por favor corrígeme en los comentarios si estoy hablando tonterías.
- Nivel de agitación: conjuntos de bandas: corta de forma segura el código innecesario. Otras opciones pueden hacer algún tipo de aumento de tamaño (no lo he notado en casa), pero no tan seguro.
- Sistema de compilación: Gradle (le permite activar la opción Minificar).
- Minify - Proguard - acorta los nombres de todas las clases y variables para ahorrar bytes miserables en tamaño, pero, como beneficio adicional, hace que el código sea menos legible para evitar la ingeniería inversa.
IOS construir
Recopilo una aplicación en el macbook de mi esposa (recuerdo que tomaron el MacBook Air más barato de 2015).
Para compilar para iOS 7 incluso en Xcode versión 9.3, fue suficiente para introducir manualmente el valor 7.0 en el campo Destino de implementación (en la pestaña General ).
Para agregar idiomas (a los cuales traduje la aplicación usando Lean Localization) a la descripción de la aplicación en la AppStore, tuvimos que agregar las siguientes líneas al archivo info.plist (en cualquier lugar, por ejemplo, inmediatamente después de <dict>):
<key>CFBundleLocalizations</key> <array> <string>English</string> <string>Russian</string> </array>
Ahora estoy usando Unity 2017.4 para compilar para iOS (como escribí anteriormente, necesito soporte para iOS 7, de lo contrario usaría 2018.1).
Tamaño de compilación de iOS
Ahora el tamaño del archivo descargado para mi iPhone es de 44 MB.
Desafortunadamente, en iOS no puedo usar sprites Crunched, porque no son compatibles con dispositivos anteriores al iPhone 5s ( sin soporte para Metal y OpenGL ES 3.0 ).
Cuando intenté reducir el tamaño de construcción a cualquier costo, el tamaño más pequeño (34 MB) se obtuvo si:
- use Unity 2018 (es decir, la versión mínima admitida es iOS 8),
- API de gráficos selecciona solo Metal,
- deje solo Target Architectures x64,
- usa texturas crujientes.
Pero todavía no he descubierto cómo trabajar con el adelgazamiento de la aplicación ; esto es algo que permite que la tienda de aplicaciones cree automáticamente mi aplicación para un iPhone / iPad / iPod específico del usuario final (lo que conduce a una disminución en el tamaño del archivo descargado). Solo tuve tiempo de redactar artículos en mis marcadores:
La configuración de mi reproductor que quiero compartir:
- Es conveniente ingresar el ID del equipo de firma automática una vez (puede obtenerlo en el sitio web del desarrollador de Apple aquí Cuenta> Membresía ) y marque la casilla Firmar automáticamente para que no lo haga cada vez más tarde en Xcode.
- Configuré la frecuencia del acelerómetro en Desactivado (deshabilité el acelerómetro), porque no lo uso. Puedo ahorrarle a la gente un poco de batería.
- Comportamiento en segundo plano - Suspender : de esta forma, la aplicación no se cierra cuando presiona el botón Inicio, pero continúa trabajando en segundo plano (por ejemplo, puede capturar este evento usando OnApplicationPause para guardar el juego).
Cómo elegí el nombre y qué usé para la promoción
¿Cuántos usaron Booking y TripAdvisor, pero nunca me di cuenta de que su nombre en la AppStore no es solo Booking, sino “Booking.com Travel Deals” y “TripAdvisor Hotels Restaurants” (el nombre se diluye con palabras clave, por lo que la aplicación se basa en estas palabras clave encontrado en busca de apstor). Por lo tanto, decidí no usar el antiguo nombre Math4Ami, pero jugué durante mucho tiempo con diferentes palabras para incluir las palabras clave que necesitaba. Al final, primero llegué a Pocket Money: Math, y luego a Learn Math & Earn Pocket Money. En ruso, estas opciones sonaban como Pocket Money for Maths y Pocket Money and Maths: Learn and Earn.
Promocioné mi aplicación enviando / publicando enlaces a amigos y conocidos, escribí dos artículos en mi blog y colgué un banner en el mismo lugar.
Por cierto, si coloca esta línea en las páginas web <head>:
<meta name="apple-itunes-app" content="app-id=1372434662" />
.. luego, al abrir esta página en el iPhone, todos verán el banner de su aplicación en la parte superior.
Descargar estadísticas
Primero lancé la versión de iOS.

Mucha gente habló de la aversión por los dispositivos de Apple y se convenció de que Android es mucho más genial. Decidí verificar y, después de 20 días de procedimientos con el ensamblaje del archivo apk, hice un lanzamiento en Google Play.

No sacará conclusiones objetivas (o ninguna), sino puramente subjetivo: esperaba más de la plataforma de Google, pero en este momento resultó ser medio peor que Apple.
Lamento eso:
- No hice copias de seguridad al cambiar a la nueva versión de Unity,
- no usó un sistema de control de versiones (como git),
- Traté de trabajar con Perforce (solo un sistema terrible, ralentiza el desarrollo de forma poco realista),
- no he usado ScriptableObject (SO) antes, es genial
- Escribí el código en una hoja larga (da miedo recordar cómo refactoré esta hoja más adelante),
- No sabía cuáles eran los olores del código , pero cómo necesitaba saber sobre ellos,
- Traté de usar variables globales en todas partes, y no locales (pensando paranoico que si solicito una función con frecuencia, entonces la variable local dentro de la función se creará una y otra vez, y solo habrá una global. Como resultado, después de cientos de llamadas a la función con variables locales, Tendría un montón de memoria desperdiciada y pérdida de rendimiento debido al recolector de basura),
- No siempre me adherí a un estilo uniforme en el código y en el nombre de todos los activos. Aquí hay un buen modelo a seguir para UE4 (hay muchas cosas útiles sobre cómo nombrar activos y también lo uso en Unity),
- Olvidé que escribo la aplicación principalmente para mi hija, y no por un código hermoso o para complacer a otros usuarios.
Me di cuenta de que:
- los niños son muy fáciles de sentar en mi aplicación (inmediatamente después de instalar la aplicación, pueden colgarla durante horas hasta que la batería del teléfono se siente),
- los niños son adictos a las matemáticas en mi solicitud, incluso si no hablan de dinero. Si hay dos niños en la familia, incluso se pelea por teléfono para resolver ejemplos,
- Mi aplicación se aburre muy rápido para los niños. Al día siguiente, pocas personas jugaron la aplicación, incluso si el niño se dio cuenta de que recibiría dinero por ello,
- la mala retención del usuario / niño no es exactamente el problema de mi aplicación específicamente, sino los detalles de la enseñanza de los niños (esto me lo dijeron los maestros de la escuela). La aplicación debe ser muy diversa para mantener el interés en los niños todo el tiempo,
- con bastante frecuencia, padres e hijos malinterpretan el principio de la aplicación y piensan que al resolver ejemplos recibirán dinero de mí (del desarrollador). Recibí diferentes cartas con preguntas como: cómo retirar dinero, puedo retirarlo a webmoney o paypal, dónde especificar la dirección para enviar dinero con cheque, etc.
- Si se disculpa por sus errores y descuidos en las respuestas a las malas críticas (y también explica cómo debería funcionar realmente), entonces las personas tienden a perdonar los errores y eliminar las malas calificaciones,
- no llegas lejos en tu propia promoción,
- los niños crecen muy rápido y mientras escribía la aplicación, mi hija ya la superó. ¡Pero mi nuevo "probador" está creciendo!
Referencias
Lista de enlaces del artículo en el orden de su mención:
+ Cómo mantener un estilo de código único C # Style Guide con Unity en mente .
+ GitHub y video sobre cómo atornillar git a Unity .
+ Hay un repositorio privado gratuito en GitLab o Bitbucket .
+ Audacity gratis para grabar y editar audio.
+ Cómo eliminar el retraso del sonido .
+ Unity Android Build Video Tutorial - Cómo hacerlo
+ Video Cómo firmar una aplicación de Unity para Android Market .
+ Dispositivos Apple compatibles con Metal / OpenGL ES 3 .
+ Disminución de la aplicación (documentación de Apple).
+ Aplicación de adelgazamiento (ayuda de Unity).
+ AssetBundle Workflow (documentación de Unity).
+ Dónde obtener la identificación del equipo .
+ ¿Qué son los olores de código ?
+ El principio de nombrar activos / recursos en proyectos de juegos en UE4 .
Gracias por leer!