VkQuality Unity 引擎插件

适用于 Unity 引擎的 VkQuality 插件可提供启动时间建议 图形 API(Vulkan 或 OpenGL ES),以便在特定设备上 设备。

VkQuality 建议在一组比 Unity 更加受限的设备上使用 Vulkan 引擎的默认许可名单。使用 VkQuality 即可获享 使用 Vulkan,同时将 Vulkan 的使用范围限制为具有较新图形的较新设备 驱动程序,这可以限制游戏出现驱动程序问题的风险。仅 VkQuality 因为我们仍然可以 在推荐设备上遇到驱动程序问题。VkQuality 支持自定义列表、 以便添加或移除系统推荐的设备 。

在 Unity 引擎游戏中启用 Vulkan

VkQuality 要求您的游戏同时具有 OpenGL ES 和 Vulkan 渲染程序 已在 Unity 项目设置中启用。使用自动 图形 API 选项,或手动设置图形 API。

获取适用于 Unity 引擎的 VkQuality 插件

从 GitHub 下载 VkQuality 插件。该插件 与 Unity 2021 及更高版本兼容。使用 Unity 2021 LTS 或更高版本以启用 Android 上的 Vulkan。插件包包含一个基本示例项目, 用于在启动时设置图形 API,然后显示一个设置为 设备的有效图形 API。

管理 VkQuality Vulkan 建议列表

VkQuality 中包含受支持设备的默认推荐列表。对于 有关如何使用自定义推荐列表的信息,请参阅使用自定义推荐列表 建议列表部分。

建议列表包括三类:

  • Vulkan 设备许可名单
  • GPU 建议许可名单
  • GPU 建议拒绝列表

设备许可名单匹配

VkQuality 先会检查活跃设备是否包含在设备允许范围内 以及运行的 Android 版本和 Vulkan 驱动程序是否最低 该设备的许可名单中指定的版本。如果满足了这些条件 VkQuality 通过返回 RECOMMENDATION_VULKAN_BECAUSE_DEVICE_MATCH 枚举值。

设备在许可名单中,但运行的是 Android 版本或驱动程序 版本低于许可名单中为其指定的最低版本 (VkQuality) 通过返回 RECOMMENDATION_GLES_BECAUSE_OLD_DRIVER 来推荐 OpenGL ES。

GPU 建议一致

如果在设备许可名单中找不到匹配的设备,VkQuality 就会评估 根据 GPU 建议允许和拒绝 GPU 型号和驱动程序版本 列表。如果 GPU 型号和驱动程序版本与 GPU 中的某个条目匹配 推荐许可名单,VkQuality 通过返回 RECOMMENDATION_VULKAN_BECAUSE_PREDICTION_MATCH 枚举常量。

如果 GPU 型号和驱动程序版本与 GPU 中的条目匹配 建议拒绝名单,VkQuality 通过返回 RECOMMENDATION_GLES_BECAUSE_PREDICTION_MATCH

不匹配的推荐内容

如果未找到匹配项,如果 Android API 级别为 正在运行的设备不低于 建议列表。默认推荐列表的未来 API 级别为 36,表示在搭载 API 级别 36 或更高级别的不匹配设备上,VkQuality 返回 RECOMMENDATION_VULKAN_BECAUSE_FUTURE_ANDROID 枚举常量。

如果在设备许可名单或 GPU 建议列表中找不到匹配项, 并且设备的 API 级别低于 Future API 级别,即 VkQuality 通过返回 RECOMMENDATION_GLES_BECAUSE_NO_DEVICE_MATCH 来推荐 OpenGL ES。

将 VkQuality 归档文件添加到项目中

VkQuality 插件是 VkQuality-1.x.x.aar 文件,位于 已下载软件包归档的 Assets/Android/Plugins 目录。实际 .aar 文件的版本号与软件包的版本号一致 归档名称。如需安装该插件,请执行以下步骤:

  1. 将该 .aar 文件复制到您的Assets/Android/Plugins 项目。(创建所需的 AndroidPlugins 子目录,如果需要 不存在。)
。 <ph type="x-smartling-placeholder">
</ph> 所需项目目录中的 VkQuality .aar 文件。
图 1. 所需项目目录中的 VkQuality .aar 文件。
  1. 在 Unity Project 层次结构中选择 VkQuality-1.x.x 插件文件 在 Inspector 窗格中打开 Import Settings。请确保 已选中 Android 平台。
图 2. VkQuality 插件平台导入设置。
图 2. VkQuality 插件平台导入设置。

使用自定义 activity 调用 VkQuality

与典型的 Unity 引擎插件不同,必须执行 VkQuality 才能获得 图形 API 建议。然后,您可以使用 Unity 播放器命令行参数功能来设置 根据 VkQuality 建议生成的图形 API。在 Android 上,传递 命令行参数要求覆盖 UnityPlayerActivity创建一个自定义 activity

如果您的游戏已在使用自定义 activity,请参阅将 VkQuality 添加到 现有自定义活动部分。要创建新的自定义活动,请执行以下操作: 请参阅下一部分中的向 Unity 项目添加自定义 activity

向 Unity 引擎项目添加自定义 activity

插件中包含使用 VkQuality 的自定义 Activity 示例 软件包位于 Assets/Plugins/Android/VkQualityTestActivity.java 中。 如需自定义该文件并在游戏中使用,请按以下步骤操作:

  1. VkQualityTestActivity.java 文件复制到 Assets/Plugins/Android 目录中。
  2. 将其重命名为适合您游戏的名称(例如, MyGameActivity.java)。
  3. 在文本编辑器中打开该文件。
  4. 将类名称从 VkQualityTestActivity 更改为您为 文件(例如 MyGameActivity.java)。
  5. 将软件包名称从 com.google.android.games.VkQualityTest 更改为 与 Unity Project Settings 中 Package Name 字段的值一致 其他设置下的玩家类别(例如, com.mycompany.mygame)。
  6. 保存并关闭该文件。

添加一个引用您的自定义 activity 的自定义清单文件,并告知 Unity 使用您的自定义清单文件:

  1. Assets/Plugins/Android 复制 AndroidManifest.xml 文件 将插件软件包的目录复制到项目的 Asset/Plugins/Android 中 目录。
  2. 在文本编辑器中打开该文件。
  3. activity android:name 设置的值从 com.google.android.games.VkQualityTest.VkQualityTestActivity至 您在前面的步骤中使用的软件包和 activity 名称(例如, com.mycompany.mygame.MyGameActivity)。
  4. 保存并关闭该文件。
  5. 打开 Unity 设置窗口,然后选择 Player 设置。展开 Publishing Settings(发布设置)部分,然后选中 Custom Main Manifest(自定义主清单) 复选框。
。 <ph type="x-smartling-placeholder">
</ph> 图 3. Unity Player 设置中的“Custom Main Manifest”选项。
图 3. Unity Player 设置中的 Custom Main Manifest 选项。

您的项目现已设置为使用在 并根据 VkQuality 建议选择 Vulkan 或 OpenGL ES。

将 VkQuality 添加到现有自定义 activity

如果您的游戏已有用于替换默认设置的自定义 activity UnityPlayerActivity,通过添加 以下代码:

首先,将 VkQuality import 语句添加到顶部的导入列表中 自定义 activity 文件:

Kotlin

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

Java

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

接下来,在 Activity 类的正文中为 图形 API 选项:

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;

创建一个变量来跟踪 API 选择:

Kotlin

private var apiOverride = OVERRIDE_NONE

Java

private int apiOverride = OVERRIDE_NONE;

将以下函数添加到您的 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);
  }
}

onCreate() 替换项的顶部调用 CheckVkQuality 函数 函数:

Kotlin

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

Java

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

最后,添加 updateUnityCommandLineArguments() 函数的替换项。 该函数使用 apiOverride 的值将命令行参数传递给 Unity 引擎,用于指定要使用的图形 API:

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;
}

您的自定义 activity 现在会在启动时调用 VkQuality 并选择 Vulkan 或 OpenGL 根据 VkQuality 建议的 ES。

使用自定义推荐列表

通过传递文件名来指定自定义推荐列表文件 将包含列表的列表传递给 StartVkQuality(),而不是传递空字符串:

Kotlin

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

Java

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

VkQuality 先在应用的内部存储空间中查找该文件 目录。如果文件不在内部存储空间中,VkQuality 会尝试加载 文件。如果文件不在上述任一位置 VkQuality 会返回 ERROR_MISSING_DATA_FILE 枚举值。

如需创建自定义推荐列表文件,请使用 VkQuality List Editor 该工具位于 GitHub 代码库中有关 README 文件。