Simplifique las construcciones de edificios en Unity3D

Más recientemente, me di cuenta de que con el creciente número de proyectos terminados, se debe dedicar más y más tiempo a la construcción de edificios. Esto no quiere decir que la unidad de alguna manera complica mucho este proceso, pero ciertamente no lo simplifica. Especialmente cuando cada proyecto se ensambla para varias plataformas e incluso en diferentes configuraciones. En principio, el problema no es nuevo y tiene muchas soluciones diferentes. Pero por varias razones, decidí escribir mi propio complemento.


Se parece a esto:



Y por qué, por qué, dónde conseguirlo y cómo usarlo, lo contaré a continuación.


Dolor


El primer malestar generalmente se siente cuando se prepara más de una plataforma para su lanzamiento. Resulta que en la unidad algunas configuraciones de proyecto son comunes para todas las plataformas, y otras no. Y esto siempre debe ser recordado y tomado en cuenta. Pero en general puedes vivir.


Entonces resulta que no hay forma de guardar diferentes configuraciones dentro de la misma plataforma. Un ejemplo simple: solo hay una compilación, pero hay muchos sitios en los que se distribuirá. Y para cada uno necesitas algo diferente. Este problema se resuelve parcialmente poniendo la configuración en la configuración de tiempo de ejecución en StreamingAssets. Pero solo parcialmente, porque de esta manera solo puedes configurar lo que está sucediendo dentro del juego. No puede reemplazar un icono de esta manera. Cada vez que necesite cambiar el ícono usted mismo. Ya sea por código, por manos, pero por ti mismo. Y en algún momento, el gerente responsable a quien entrenó para trabajar con StreamingAssets durante un mes se va de vacaciones y ayer se necesitan construcciones.


Más adelante, descubrirá que se planea una versión coreana separada, que todo debería ser diferente allí y que no puede prescindir de #ifdef aquí.


Y luego te dicen que el juego debe ser lanzado en plataformas móviles, playstation, nintendo y lavadoras.


Como resultado, la preparación de cada nueva construcción a lo largo del tiempo se vuelve similar a esto:



Verifique las lecturas, encienda el interruptor de palanca a la izquierda, gire la palanca a la derecha, apriete la válvula roja. No confundas y no olvides.


Al principio, aún puede ser nada, pero se cansa rápidamente. Y recuerda todas las manipulaciones en un mes o dos.


Cuales son tus opciones?


Internet y la sabiduría popular nos ofrecen lo siguiente:


  • Resolver un problema a nivel de proyecto. Las implementaciones de este enfoque pueden ser diferentes: proyectos separados con código y activos comunes, submódulos en un git, ramas en un git y similares.
    No puedo considerar esto seriamente. Para cercar un jardín en aras de reemplazar el icono, y luego también apoyarlo. Todo un aficionado. Pero lo vio con sus propios ojos, por lo que no pudo evitar mencionarlo.
  • Bash / bat / python / ... scripts.
    Ya mas calido. Pero requiere conocimiento adicional y es difícil llamarlo multiplataforma (a menudo parte del equipo se desarrolla bajo los makos, parte bajo Windows). Una vez más, los scripts deben ser compatibles, y este no es siempre el momento.
  • Script de editor en la propia unidad.
    Muy cálido Rotamos el proyecto dentro de la unidad como queramos. Y si utiliza el método estático y BuildPipeline, puede configurar CI. Como regla, los artículos sobre la unidad y CI describen esto. Sin embargo, un inconveniente del enfoque anterior permanece aquí: este es el código y debe escribirse, agregarse y mantenerse. Necesitamos algo similar, pero sin la necesidad de que cada plataforma y configuración ingrese al código.

Está resuelto. Estamos escribiendo nuestro complemento, con UI y hadas.


Necesitamos un plan


Primero debe decidir qué queremos obtener y por qué.


  1. Almacenamiento de la configuración del proyecto para cada configuración (aquí puede ir a la terminología del complemento en sí y llamarlas opciones). Es deseable implementar la herencia de opciones. Por ejemplo, para todas las compilaciones independientes, la configuración del proyecto será común, y las opciones entre sí solo diferirán en el icono y el nombre del proyecto. Es bastante lógico resolver esto por herencia, en lugar de copiar y pegar.
  2. Representación visual de lo que varía en una realización particular y cómo difiere de la configuración actual del proyecto.
  3. Combinando opciones en una colección. Para poder recopilar un subconjunto de compilaciones con un botón o un método estático a la vez.
  4. Embalaje de la compilación en el archivo. Este es un requisito opcional. En el caso de usar el complemento en conjunto con el servidor de compilación, este elemento se puede implementar de forma paralela. Pero quiero simplificar la vida para simplificar todo, pero no siempre hay un servidor de compilación.
  5. Mover archivos en diferentes etapas de ensamblaje. Por ejemplo, debe reemplazar algún activo (icono, bienvenida, escena, etc.) antes de ensamblar (reemplazar los activos en este caso debe ser reversible, la construcción de la construcción no debe cambiar el estado actual del proyecto). O cambie el nombre de la compilación de Windows terminada {exe_name} _Data to Data (comportamiento de unidad muy molesto, sin esta manipulación no puede cambiar el nombre del ejecutable). O, de nuevo, en las compilaciones de Windows, organice los StreamingAssets necesarios. Debe hacer esto antes de empaquetar el archivo. Y luego, por ejemplo, arrastre todos los archivos a algún lugar en un lugar.
  6. Los proyectos de unidad tienen una gran cantidad de configuraciones y no queremos escribir nuestra propia interfaz de usuario para todos ellos. Además, él ya está en la unidad misma. Por lo tanto, cambiaremos la configuración del proyecto como de costumbre, y en el complemento simplemente seguimos los cambios en la configuración y guardamos las opciones necesarias.
  7. Me gustaría almacenar cada opción en un archivo separado para que sea posible arrastrarlas entre proyectos.
  8. Es recomendable trabajar con Unity desde la versión 5.6. Hay algunos proyectos heredados con mucho alboroto en torno a las compilaciones.

Condujo


La parte principal de nuestro complemento es trabajar con la configuración del proyecto, así como almacenar y procesar opciones de configuración individuales. Por lo tanto, nos centraremos en esto.


La unidad almacena todas las configuraciones en el directorio ProjectSettings en la raíz del proyecto. Y lo primero al iniciar guardaremos esta configuración en el directorio de complementos (por cierto, se trata de BuildVariants en la raíz del proyecto). Esto es necesario para que podamos rastrear todos los cambios posteriores. A continuación, tenemos que almacenarlos de alguna manera. Lo más fácil sería simplemente copiar ProjectSettings a una ubicación separada para cada opción. Y en el momento de su activación, simplemente reemplácelos enteros. La idea está funcionando bastante y al principio lo consideré. Pero esto nos priva por completo de la oportunidad de heredar opciones. Y si ya estamos escribiendo un complemento, lo haremos de inmediato de manera hermosa. Por lo tanto, debemos aprender a leer y escribir el contenido de ProjectSettings.


Para hacer esto, debe comprender lo que está almacenado allí. Y los activos más comunes se almacenan allí, que se serializan y deserializan de manera regular. Esto significa que podemos leerlos a través de AssetsDatabase y obtener SerializedObject. Esto ya es algo. Debido a que podemos pasar por toda la Propiedad Serializada, rastrear sus diferencias con la "instantánea" original y guardarlas como una variante. Luego, al ensamblar o activar la variante, recopilamos los cambios a lo largo de toda la cadena de herencia, los aplicamos a la "instantánea" y los deslizamos en ProjectSettings. Voila


Pero SerializedProperty tiene algunas características desagradables: una forma de almacenar valores (todos estos intValue, floatValue, isArray), la falta de un mecanismo normal para compararlos (hay dos objetos relacionados, ¿cómo entendemos si todos los SerializedProperty tienen los mismos valores?) Y paradójico (y tal vez no) la ausencia del atributo Serializable (lo que significa que necesitaremos un contenedor para guardar). No puedo decir que estos son algunos defectos fatales. Todo esto se ha hecho más de una vez en numerosos guiones de editor. Pero aún quiero algo más simple, comprensible y universal.


¿O tal vez limitaremos ligeramente el uso de nuestro complemento? Deje que funcione solo en proyectos con serialización de activos basada en texto (¿alguien más usa binario?). Luego, todos los ProjectSettings se almacenarán como documentos yaml. Puede tomar la biblioteca YamlDotNet y usarla para analizar y guardar la configuración. Al mismo tiempo, almacene sus configuraciones en yaml. Así que aún más claramente. Solo necesita agregar algunas extensiones para diferencias de documentos yaml y su combinación.


Alborotarse un poco con la ventana del editor (ni siquiera quiero describir, espero que vivir con UIElements sea más fácil y más divertido), se hace todo en un montón.


Resultado


Es hora de mostrar lo que hice . Ya se ha familiarizado con los principales mecanismos de la operación del complemento, por lo tanto, se trata de una tesis adicional sobre algunas características:


  • Las opciones se agregan a la colección seleccionada utilizando una marca de verificación a la izquierda del nombre.
  • La ruta de compilación debe especificarse con la extensión. No encontré una lista completa de extensiones para todos los BuildTarget posibles, así que lo dejé hasta ahora.
  • Mover archivos se hereda de la misma manera que la configuración.
  • No se han implementado matrices de diferencias. Por lo tanto, si en la versión heredada cambió algo en la lista de escenas, la lista completa se reemplazará por completo. El bien deberá ser finalizado.
  • La configuración actual del proyecto diff es una lista de todas las diferencias entre la opción seleccionada y la configuración actual del proyecto. Además, si se selecciona la opción activa, se pueden deshacer los cambios en la configuración actual.
  • Las configuraciones de variantes son, en consecuencia, cambios individuales en la opción seleccionada, excluyendo los cambios parentales.
  • Cuando se activa la opción, se perderán todos los cambios no guardados en la configuración del proyecto.
  • Si hay cambios no guardados en la configuración del proyecto, cualquier intento de compilar la compilación a través del complemento finalizará con la ejecución. Porque ver arriba, y como recordamos, la construcción de la construcción no debería cambiar el estado actual del proyecto.
  • El complemento se puede usar junto con el servidor de compilación. Existen métodos estáticos para esto: BuildVariants.Controller.BuildController.BuildAll, BuildVariants.Controller.BuildController.BuildCollection (con el nombre de la colección en el parámetro -collection) y BuildVariants.Controller.BuildController.BuildVariant (con el nombre de la variante en el parámetro -variante). Se verá más o menos así:
    $unity_path -batchmode -projectPath $project_path -quit -logfile -executeMethod BuildVariants.Controller.BuildController.BuildCollection -collection standalone
  • Para archivar, el complemento tiene otra dependencia en forma de biblioteca DotNetZip.
  • El complemento se escribió en las condiciones de una pequeña pausa de trabajo, por lo que todavía no hay oportunidad de probarlo y moderarlo en feroces batallas. Puede haber errores, tal vez incluso malos y desagradables.

Planes futuros


Por supuesto, quiero alimentar las características del complemento indefinidamente, pero es hora de volver a proyectos reales y, al mismo tiempo, probar la funcionalidad existente. Un poco más tarde quiero aplicar UIElements para nuevas versiones de la unidad, espero que esto lo haga más hermoso y conveniente. También me gustaría atornillar versiones y algunas semejanzas de variables de entorno. Tal vez el público le dirá algo más sobre funcionalidad o usabilidad.


Por lo tanto, me complacerá recibir sugerencias, comentarios, preguntas e informes de errores. ¡Construcciones fáciles para ti!

Source: https://habr.com/ru/post/es433460/


All Articles