Muchas de las APIs de Unity y estructuras de proyecto son idénticas para todas las plataformas soportadas, y en algunos casos un proyecto puede simplemente ser reconstruido para ejecutarse en diferentes dispositivos. Sin embargo, las diferencias fundamentales en el hardware y en métodos de despliegue hacen que algunas partes del proyecto no puedan ser portadas entre plataformas sin haber hecho cambios. A continuación se encuentran detalles de algunos problemas comunes de plataforma cruzada, y sugerencias para solucionarlos.
El ejemplo más obvio del comportamiento distinto entre plataformas es en los métodos de entrada ofrecidos por el hardware.
La función Input.GetAxis es muy conveniente en plataformas de escritorio como una forma de consolidar la entrada desde el teclado y el joypad. Sin embargo, esta función no tiene sentido para las plataformas móviles que se basan en la entrada por medio de la pantalla táctil. Igualmente, la entrada de teclado estándar de escritorio no porta bien en móviles para otras cosas que no sean texto escrito. Vale la pena agregar una capa de abstracción al código que maneja la entrada, si consideras en el futuro portar el juego a otras plataformas. A modo de un ejemplo simple, si estuvieras haciendo un juego de conducir entonces podrías crear tu propia clase de entrada y envolver los llamados de API de Unity usando tus propias funciones:-
// Devuelve valores en el rango de -1.0 .. +1.0 (== left .. right).
function Steering() {
return Input.GetAxis("Horizontal");
}
// Devuelve valores en el rango de -1.0 .. +1.0 (== accel .. brake).
function Acceleration() {
return Input.GetAxis("Vertical");
}
var currentGear: int;
// Devuelve un entero que corresponde al engranaje seleccionado.
function Gears() {
if (Input.GetKeyDown("p"))
currentGear++;
else if (Input.GetKeyDown("l"))
currentGear--;
return currentGear;
}
Una ventaja de envolver los llamados de API en una clase como esta es que todos ellos están concentrados en un solo archivo fuente, y en consecuencia, será fácil su localización y reemplazo. Sin embargo, lo más impontante es que debes diseñar tus funciones de entrada de acuerdo al significado lógico de las entradas en tu juego. Esto será de ayuda para aislar del resto del código del juego el método específico de entrada usado con una plataforma en particular. Por ejemplo, la función Gears de arriba podría ser modificada para que la entrada real provenga de toques en la pantalla de un dispositivo móvil. Si se usa un integer para representar la indumentaria escogida, esto funcionará bien en todas las plataformas; pero si se mezcla con el resto del código los llamados de API específicos a la plataforma, esto causará problemas. Puedes ver conveniente el utilizar compilación dependiente de la plataforma para combinar las diferentes implementaciones de las funciones de entrada en el mismo archivo fuente, para evitar intercambios manuales.
Las funciones Input.GetMouseButtonXXX están diseñadas para que tengan una interpretación razonablemente obvia en dispositivos móviles aunque no haya un “mouse” como tal. Un simple toque en la pantalla será reportado como un clic con el botón izquierdo del mouse, y la propiedad Input.mousePosition devuelve la posición del toque mientras el dedo está tocando la pantalla. Esto significa que los juegos que tengan interacción simple de mouse usualmente pueden trabajar transparentemente entre las plataformas de escritorio y móvil. Naturalmente, no obstante, con frecuencia la conversión es mucho menos sencilla que esto. Un juego de escritorio puede hacer uso de más de un botón del mouse, y un juego para móviles puede detectar múltiples toques en la pantalla al mismo tiempo.
Al igual que con los llamados de API, el problema puede ser manejado de forma parcial representando la entrada con valores lógicos que son luego usados por el resto del código del juego. Por ejemplo, un gesto de “pellizco” para dar zoom en un móvil podría ser reemplazado por un botón/atajo de + y - en la version de escritorio; la función de entrada podría simplemente devolver un valor float que especifique el factor de zoom. Igualmente, podría ser posible usar un tap con dos dedos en móviles para reemplazar el clic con el botón derecho del mouse. Sin embargo, si las propiedades del dispositivo de entrada son una parte integral del juego, entonces no puede ser posible remodelarlos en una plataforma diferente. Esto puede significar que el juego no puede ser portado a todas ellas, o que la entrada y/o la mecánica de juego necesiten ser modificadas ampliamente.
Estas entradas provienen de la movilidad de los dispositivos móviles, por lo que puede ser que no tengan un equivalente significativo en el ambiente de escritorio. Sin embargo, en algunos casos sólo son un reflejo de controles estándar de juegos y pueden ser portados muy fácilmente. Por ejemplo, un juego de conducción podría implementar el control de dirección a partir de la inclinación de un dispositivo móvil (determinada por el acelerómetro). En casos así, los llamadas API para entrada usualmente son fáciles de reemplazar, de modo que la entrada del acelerómetro puede ser reemplazada por pulsaciones del teclado, por decir algo. Sin embargo, puede ser necesario recalibrar las entradas o incluso variar la dificultad del juego para tener en cuenta cada método de entrada distinto. Inclinar un dispositivo es más lento y eventualmente más agotador que presionar teclas, y también puede hacer más difícil que el jugador se concentre en la pantalla. Esto puede resultar en que el juego se vuelva más difícil de dominar en un móvil, de modo que puede ser apropiado frenar el ritmo de la mecánica de juego o conceder más tiempo por nivel. Esto requerirá que el código del juego sea diseñado para que estos factores puedan ser ajustados con facilidad.
Los dispositivos móviles inevitablemente tienen menos almacenamiento, memoria y potencia disponible de CPU que las máquinas de escritorio, y por consiguiente un juego puede ser difícil de portar sólo por el hecho de que su desempeño no sea aceptable en hardware poco potente. Algunos problemas de recursos pueden ser manejados pero si estás empujando los límites del hardware en un ambiente de escritorio, es probable que tu juego no sea un buen candidato para ser portado a una plataforma móvil.
Hoy en día, los dispositivos móviles son altamente dependientes del soporte de hardware para permitir la reproducción de películas. El resultado es que estas opciones de reproducción son limitadas e indudablemente no ofrecen la flexibilidad que el asset MovieTexture tiene en plataformas de escritorio. Las películas pueden ser reproducidas en pantalla completa en móviles, pero no hay enfoque alguno sobre usarlos para texturizar objetos dentro del juego (así que no es posible mostrar una película en una pantalla de TV dentro del juego, por ejemplo). En términos de portabilidad, está bien usar películas para introducciones, vídeos con escenas de la historia (cutscenes), instrucciones y otras presentaciones sencillas. Sin embargo, si las películas necesitan ser visibles dentro del escenario de juego entonces debes considerar si las opciones de reproducción en móviles serán lo adecuado.
El video, el audio e incluso las texturas pueden usar una gran cantidad de almacenamiento y podrías necesitar tener esto en mente si quieres portar tu juego. El espacio de almacenamiento (el cual con frecuencia también corresponde al tiempo de descarga) no es usualmente un problema en máquinas de escritorio, pero este no es el caso con los móviles. Además, las tiendas de aplicaciones móviles imponen un límite sobre el tamaño máximo de un producto enviado. Puede requerir algo de planeación para abordar estos asuntos durante el desarrollo de tu juego. Por ejemplo, podrías necesitar el proporcionar versiones simplificadas de los assets para móviles a fin de ahorrar espacio. Otra posibilidad es que el juego pueda necesitar ser diseñado para que los assets grandes puedan ser descargados bajo demanda en lugar de ser parte de la descarga inicial de la aplicación.
La recuperación de la memoria no usada a partir de los objetos “muertos” es manejada automáticamente por Unity, y se efectúa con frecuencia y de forma imperceptible en las máquinas de escritorio. No obstante, las bajas prestaciones en memoria y potencia de CPU en los móviles hacen que la recolecciones de basura puedan ser más frecuentes, y el tiempo que éstas tomen puede impactar más intensamente sobre el desempeño (causando pausas no deseadas en el transcurso del juego, etc). Incluso si el juego se ejecuta con la memoria disponible, puede ser necesario optimizar el código para evitar las pausas de recolección de basura. Puede encontrarse más información en la página sobre gestión de memoria.
Un juego que se ejecute bien en una máquina de escritorio podría sufrir de una baja velocidad de cuadros en un móvil, debido a que el CPU de un móvil tiene que lidiar con la complejidad del juego. Por tanto, se puede necesitar el poner atención extra a escribir un código más eficiente cuando un proyecto es portado a una plataforma móvil. Un número de pasos simples para mejorar la eficiencia son explicados en esta página del manual.