Complemento del motor VkQuality para Unity

El complemento VkQuality para el motor de Unity proporciona recomendaciones en el momento de inicio de la API de gráficos (OpenGL ES o Vulkan) para usar en tu juego en dispositivos específicos.

VkQuality recomienda Vulkan en un conjunto de dispositivos más restringido que la lista de permitidos predeterminada del motor de Unity. Usa VkQuality para obtener los beneficios de rendimiento de Vulkan y limitar su uso a dispositivos más nuevos con controladores de gráficos más nuevos, lo que limita la exposición del juego a problemas con los controladores. VkQuality solo hace recomendaciones de calidad, no garantías, ya que es posible encontrar problemas con los controladores en los dispositivos recomendados. VkQuality admite listas personalizadas, lo que te permite agregar o quitar recomendaciones de dispositivos para tu juego.

Cómo habilitar Vulkan en tu juego para el motor de Unity

VkQuality requiere que tu juego tenga habilitados los procesadores de OpenGL ES y Vulkan en la configuración del proyecto de Unity. Habilita los procesadores con la opción Auto Graphics API o mediante la configuración manual de las APIs de gráficos.

Cómo obtener el complemento VkQuality para el motor de Unity

Descarga el complemento VkQuality desde GitHub. El complemento es compatible con Unity 2021 y versiones posteriores. Usa Unity 2021 LTS o una versión posterior para habilitar Vulkan en Android. El paquete del complemento contiene un proyecto de ejemplo básico que usa el complemento para configurar la API de gráficos en el inicio y, luego, muestra una cadena establecida en la API de gráficos activa del dispositivo.

Administra la lista de recomendaciones de VkQuality Vulkan

VkQuality incluye una lista de recomendaciones predeterminada de dispositivos compatibles. Si deseas obtener información para usar una lista de recomendaciones personalizadas, consulta la sección Cómo utilizar una lista de recomendaciones personalizadas.

La lista de recomendaciones incluye tres categorías:

  • Lista de dispositivos permitidos de Vulkan
  • Lista de entidades permitidas de las recomendaciones de GPU
  • Lista de entidades denegadas de recomendaciones de GPU

Coincidencias de la lista de dispositivos permitidos

Primero, VkQuality verifica si el dispositivo activo se incluye en la lista de dispositivos permitidos y si ejecuta la versión mínima de Android y la versión del controlador de Vulkan especificadas en la lista de entidades permitidas de ese dispositivo. Si se cumplen estos criterios, VkQuality recomienda Vulkan mostrando el valor enum RECOMMENDATION_VULKAN_BECAUSE_DEVICE_MATCH.

Si el dispositivo está en la lista de permitidos, pero ejecuta una versión de Android o del controlador por debajo del mínimo especificado en la lista de elementos permitidos, VkQuality recomienda OpenGL ES mostrando RECOMMENDATION_GLES_BECAUSE_OLD_DRIVER.

Coincidencias de la recomendación de GPU

Si no se encuentra ninguna coincidencia de dispositivo en la lista de dispositivos permitidos, VkQuality evalúa el modelo de GPU y la versión del controlador en función de las listas de recomendaciones de GPU permitidas y denegadas. Si el modelo de GPU y la versión del controlador coinciden con una entrada en la lista de permitidos de recomendaciones de GPU, VkQuality recomienda Vulkan mostrando la constante de enumeración RECOMMENDATION_VULKAN_BECAUSE_PREDICTION_MATCH.

Si el modelo de GPU y la versión del controlador coinciden con una entrada de la lista de denegación de recomendaciones de GPU, VkQuality recomienda OpenGL ES mostrando RECOMMENDATION_GLES_BECAUSE_PREDICTION_MATCH.

Recomendaciones sin coincidencias

Si no se encuentran coincidencias, VkQuality recomienda Vulkan si el nivel de API de Android del dispositivo en ejecución es igual o superior al nivel de API Future de la lista de recomendaciones. La lista de recomendaciones predeterminada tiene un nivel de API Future de 36, lo que significa que, en dispositivos no coincidentes que ejecutan el nivel de API 36 o uno posterior, VkQuality muestra la constante de enumeración RECOMMENDATION_VULKAN_BECAUSE_FUTURE_ANDROID.

Si no se encuentran coincidencias en la lista de entidades permitidas o en las listas de recomendaciones de GPU, y el nivel de API del dispositivo es inferior al nivel de la API futura, VkQuality recomienda OpenGL ES mostrando RECOMMENDATION_GLES_BECAUSE_NO_DEVICE_MATCH.

Agrega el archivo de VkQuality a tu proyecto.

El complemento VkQuality es el archivo VkQuality-1.x.x.aar ubicado en el directorio Assets/Android/Plugins del archivo del paquete descargado. El número de versión real del archivo .aar coincide con el número de versión del nombre del archivo del paquete. Para instalar el complemento, sigue estos pasos:

  1. Copia el archivo .aar en el directorio Assets/Android/Plugins de tu proyecto. (Crea los subdirectorios Android y Plugins necesarios si no existen).
El archivo .aar de VkQuality en el directorio del proyecto requerido
Figura 1: El archivo VkQuality .aar en el directorio del proyecto requerido.
  1. Selecciona el archivo del complemento VkQuality-1.x.x en la jerarquía de Project de Unity para que aparezca Import Settings en el panel Inspector. Asegúrate de que la plataforma de Android esté marcada.
Figura 2: Configuración de importación de la plataforma del complemento VkQuality.
Figura 2: Configuración de importación de la plataforma del complemento VkQuality.

Usa una actividad personalizada para llamar a VkQuality

A diferencia de los complementos típicos del motor de Unity, VkQuality debe ejecutarse para obtener una recomendación de API de gráficos antes de inicializar el motor de Unity. Luego, usa la función de argumentos de línea de comandos del reproductor de Unity para configurar la API de gráficos según la recomendación de VkQuality. En Android, para pasar los argumentos de la línea de comandos, es necesario anular el comportamiento predeterminado de UnityPlayerActivity mediante la creación de una actividad personalizada.

Si el juego ya usa una actividad personalizada, consulta la sección Cómo agregar VkQuality a una actividad personalizada existente. Si quieres crear una nueva actividad personalizada para tu juego, consulta Cómo agregar una actividad personalizada a tu proyecto de Unity, que aparece a continuación.

Agrega una actividad personalizada a tu proyecto de motor de Unity

En el paquete de complemento de Assets/Plugins/Android/VkQualityTestActivity.java, se incluye un ejemplo de actividad personalizada que usa VkQuality. Para personalizar el archivo y usarlo en tu juego, sigue estos pasos:

  1. Copia el archivo VkQualityTestActivity.java en el directorio Assets/Plugins/Android.
  2. Cámbialo por uno adecuado para tu juego (por ejemplo, MyGameActivity.java).
  3. Abre el archivo en un editor de texto.
  4. Cambia el nombre de la clase de VkQualityTestActivity por el nombre que le asignaste al archivo (por ejemplo, MyGameActivity.java).
  5. Cambia el nombre del paquete de com.google.android.games.VkQualityTest para que coincida con el valor del campo Package Name en la categoría Player de la configuración del proyecto de Unity en Other Settings (por ejemplo, com.mycompany.mygame).
  6. Guarda el archivo y ciérralo.

Agrega un archivo de manifiesto personalizado que haga referencia a tu actividad personalizada y luego indícale a Unity que lo use:

  1. Copia el archivo AndroidManifest.xml del directorio Assets/Plugins/Android del paquete del complemento al directorio Asset/Plugins/Android de tu proyecto.
  2. Abre el archivo en un editor de texto.
  3. Cambia el valor de la configuración de activity android:name de com.google.android.games.VkQualityTest.VkQualityTestActivity a los nombres de paquetes y actividades que usaste en los pasos anteriores (por ejemplo, com.mycompany.mygame.MyGameActivity).
  4. Guarda el archivo y ciérralo.
  5. Abre la ventana de configuración de Unity y selecciona la configuración del Player. Expande la sección Publishing Settings (Configuración de la publicación) y marca la casilla de verificación Custom Main Manifest.
Figura 3: Opción Custom Main Manifest en la configuración de Unity Player.
Figura 3: La opción Custom Main Manifest en la configuración del Reproductor de Unity.

Tu proyecto ya está configurado para usar la actividad personalizada que llama a VkQuality en el inicio y elige Vulkan o OpenGL ES en función de la recomendación de VkQuality.

Cómo agregar VkQuality a una actividad personalizada existente

Si tu juego ya tiene una actividad personalizada que anula el UnityPlayerActivity predeterminado, integra las recomendaciones de VkQuality. Para ello, agrega el siguiente código:

Primero, agrega la sentencia de importación VkQuality a la lista de importaciones en la parte superior del archivo de actividad personalizada:

Kotlin

import com.google.android.games.vkquality.VKQuality;

Java

import com.google.android.games.vkquality.VKQuality;

A continuación, crea algunas constantes en el cuerpo de tu clase Activity para las opciones de la API de gráficos:

Kotlin

companion object {
  private const val OVERRIDE_NONE = 0
  private const val OVERRIDE_GLES = 1
  private const val OVERRIDE_VULKAN = 2

Java

private static final int OVERRIDE_NONE = 0;
private static final int OVERRIDE_GLES = 1;
private static final int OVERRIDE_VULKAN = 2;

Crea una variable para hacer un seguimiento de la selección de API:

Kotlin

private var apiOverride = OVERRIDE_NONE

Java

private int apiOverride = OVERRIDE_NONE;

Agrega la siguiente función a tu clase Activity:

Kotlin

private fun CheckVkQuality() {
    val vkQuality = VKQuality(this)
    val startResult = vkQuality.StartVkQuality("")
    if (startResult == VKQuality.INIT_SUCCESS) {
        // In the current release, we can assume GetVkQuality is
        // ready as soon as StartVkQuality has returned success.
        val getResult = vkQuality.GetVkQuality()
        LogVkQualityResult(getResult)
        apiOverride =
            when (getResult) {
                VKQuality.RECOMMENDATION_VULKAN_BECAUSE_DEVICE_MATCH,
                VKQuality.RECOMMENDATION_VULKAN_BECAUSE_PREDICTION_MATCH,
                VKQuality.RECOMMENDATION_VULKAN_BECAUSE_FUTURE_ANDROID -> OVERRIDE_VULKAN
                VKQuality.RECOMMENDATION_GLES_BECAUSE_OLD_DEVICE,
                VKQuality.RECOMMENDATION_GLES_BECAUSE_OLD_DRIVER,
                VKQuality.RECOMMENDATION_GLES_BECAUSE_NO_DEVICE_MATCH,
                VKQuality.RECOMMENDATION_GLES_BECAUSE_PREDICTION_MATCH -> OVERRIDE_GLES
                else -> OVERRIDE_GLES
            }
        vkQuality.StopVkQuality()
    } else {
        Log.e("VKQUALITY", "VkQuality start failed with result: $startResult")
    }
}

Java

private void CheckVkQuality() {
  VKQuality vkQuality = new VKQuality(this);
  // An empty string specifies use of the default
  // built-in device list file.
  int startResult = vkQuality.StartVkQuality("");
  if (startResult == VKQuality.INIT_SUCCESS) {
      // In the current release, we can assume GetVkQuality is
      // ready as soon as StartVkQuality has returned success.
      int getResult = vkQuality.GetVkQuality();

      switch (getResult) {
          case VKQuality.RECOMMENDATION_VULKAN_BECAUSE_DEVICE_MATCH:
          case VKQuality.RECOMMENDATION_VULKAN_BECAUSE_PREDICTION_MATCH:
          case VKQuality.RECOMMENDATION_VULKAN_BECAUSE_FUTURE_ANDROID:
              apiOverride = OVERRIDE_VULKAN;
              break;
          case VKQuality.RECOMMENDATION_GLES_BECAUSE_OLD_DEVICE:
          case VKQuality.RECOMMENDATION_GLES_BECAUSE_OLD_DRIVER:
          case VKQuality.RECOMMENDATION_GLES_BECAUSE_NO_DEVICE_MATCH:
          case VKQuality.RECOMMENDATION_GLES_BECAUSE_PREDICTION_MATCH:
          default:
              apiOverride = OVERRIDE_GLES;
              break;
      }
      vkQuality.StopVkQuality();
  } else {
      Log.e("VKQUALITY", "VkQuality start failed with result: " + startResult);
  }
}

Llama a la función CheckVkQuality desde la parte superior de una función de anulación onCreate() antes de llamar a la implementación de la clase base:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
  CheckVkQuality()
  super.onCreate(savedInstanceState)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    CheckVkQuality();
    super.onCreate(savedInstanceState);
}

Por último, agrega una anulación de la función updateUnityCommandLineArguments() que use el valor de apiOverride para pasar un argumento de línea de comandos al motor Unity que especifique la API de gráficos que se usará:

Kotlin

override fun updateUnityCommandLineArguments(cmdLine: String): String {
  if (apiOverride == OVERRIDE_VULKAN) {
      Log.i("VKQUALITY", "Passing -force-vulkan")
      return appendCommandLineArgument(cmdLine, "-force-vulkan")
  } else if (apiOverride == OVERRIDE_GLES) {
      Log.i("VKQUALITY", "Passing -force-gles")
      return appendCommandLineArgument(cmdLine, "-force-gles")
  }
  Log.i("VKQUALITY", "No override passed")
  // let Unity pick the Graphics API based on PlayerSettings
  return cmdLine
}

private fun appendCommandLineArgument(cmdLine: String, arg: String?): String {
    return if (arg == null || arg.isEmpty()) cmdLine
    else if (cmdLine == null || cmdLine.isEmpty()) arg else "$cmdLine $arg"
}

Java

@Override protected String updateUnityCommandLineArguments(String cmdLine)
{
    if (apiOverride == OVERRIDE_VULKAN) {
        Log.i("VKQUALITY", "Passing -force-vulkan");
        return appendCommandLineArgument(cmdLine, "-force-vulkan");
    }
    else if (apiOverride == OVERRIDE_GLES) {
        Log.i("VKQUALITY", "Passing -force-gles");
        return appendCommandLineArgument(cmdLine, "-force-gles");
    }
    Log.i("VKQUALITY", "No override passed");
    // let Unity pick the Graphics API based on PlayerSettings
    return cmdLine;
}

private String appendCommandLineArgument(String cmdLine, String arg) {
    if (arg == null || arg.isEmpty())
        return cmdLine;
    else if (cmdLine == null || cmdLine.isEmpty())
        return arg;
    else
        return cmdLine + " " + arg;
}

Tu actividad personalizada ahora llama a VkQuality al inicio y elige Vulkan o OpenGL ES en función de la recomendación VkQuality.

Cómo usar una lista de recomendaciones personalizadas

Para especificar un archivo de lista de recomendaciones personalizadas, pasa el nombre del archivo que contiene la lista a StartVkQuality(), en lugar de pasar una string vacía:

Kotlin

val startResult = vkQuality.StartVkQuality("CUSTOM_FILE_NAME.vkq")

Java

int startResult = vkQuality.StartVkQuality("CUSTOM_FILE_NAME.vkq");

VkQuality primero busca el archivo en el directorio de almacenamiento interno de tu aplicación. Si el archivo no está en el almacenamiento interno, VkQuality intenta cargar el archivo desde los elementos del paquete de aplicación. Si el archivo no está en ninguna de las ubicaciones, VkQuality muestra el valor de enumeración ERROR_MISSING_DATA_FILE.

Para crear un archivo de lista de recomendaciones personalizado, usa la herramienta VkQuality List Editor, ubicada en el repositorio de GitHub. La documentación de la herramienta se encuentra en su archivo README.