用于 Unity 引擎的 VkQuality 插件提供启动时图形 API(Vulkan 或 OpenGL ES)建议,以用于您的游戏在特定设备上的运行。
VkQuality 在比 Unity 引擎默认允许列表更受限制的设备集上推荐 Vulkan。使用 VkQuality 可获得 Vulkan 的性能优势,同时将 Vulkan 的使用限制在配备较新图形驱动程序的较新设备上,这可以限制您的游戏暴露于驱动程序问题的风险。VkQuality 只提供质量建议,不作保证,因为在推荐的设备上仍可能遇到驱动程序问题。VkQuality 支持自定义列表,让您能够为您的游戏添加或删除设备推荐。
在您的 Unity 引擎游戏中启用 Vulkan
VkQuality 要求您的游戏在 Unity 项目设置中同时启用 OpenGL ES 和 Vulkan 渲染器。通过使用自动图形 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
枚举值来推荐 Vulkan。
如果设备在允许列表中,但正在运行低于允许列表中为其指定的最低 Android 版本或驱动程序版本,VkQuality 将通过返回 RECOMMENDATION_GLES_BECAUSE_OLD_DRIVER
来推荐 OpenGL ES。
GPU 推荐匹配
如果在设备允许列表中找不到设备匹配项,VkQuality 会根据 GPU 推荐允许列表和拒绝列表评估 GPU 模型和驱动程序版本。如果 GPU 模型和驱动程序版本与 GPU 推荐允许列表中的条目匹配,VkQuality 将通过返回 RECOMMENDATION_VULKAN_BECAUSE_PREDICTION_MATCH
枚举常量来推荐 Vulkan。
如果 GPU 模型和驱动程序版本与 GPU 推荐拒绝列表中的条目匹配,VkQuality 将通过返回 RECOMMENDATION_GLES_BECAUSE_PREDICTION_MATCH
来推荐 OpenGL ES。
无匹配项的推荐
如果未找到匹配项,并且运行设备的 Android API 级别等于或高于推荐列表中的未来 API 级别,VkQuality 将推荐 Vulkan。默认推荐列表的未来 API 级别为 36,这意味着在运行 API 级别 36 或更高版本的非匹配设备上,VkQuality 将返回 RECOMMENDATION_VULKAN_BECAUSE_FUTURE_ANDROID
枚举常量。
如果在设备允许列表或 GPU 推荐列表中未找到匹配项,并且设备的 API 级别低于未来 API 级别,VkQuality 将通过返回 RECOMMENDATION_GLES_BECAUSE_NO_DEVICE_MATCH
来推荐 OpenGL ES。
将 VkQuality 归档文件添加到您的项目
VkQuality 插件是下载包归档文件的 Assets/Android/Plugins
目录中的 VkQuality-1.x.x.aar
文件。 .aar 文件的实际版本号与包归档名称的版本号匹配。要安装插件,请执行以下步骤
- 将 .aar 文件复制到项目的
Assets/Android/Plugins
目录。(如果不存在,请创建所需的Android
和Plugins
子目录。)

- 在 Unity Project 层次结构中选择
VkQuality-1.x.x
插件文件,以在其 Inspector 窗格中调出其 Import Settings。确保选中 Android 平台。

使用自定义 activity 调用 VkQuality
与典型的 Unity 引擎插件不同,VkQuality 必须在 Unity 引擎初始化之前执行才能获得图形 API 推荐。然后,您可以使用Unity 播放器命令行参数功能根据 VkQuality 推荐设置图形 API。在 Android 上,传递命令行参数需要通过创建自定义 activity 来覆盖 UnityPlayerActivity 的默认行为。
如果您的游戏已经在使用自定义 activity,请参阅将 VkQuality 添加到现有自定义 activity 部分。要为您的游戏创建新的自定义 activity,请参阅随后的将自定义 activity 添加到您的 Unity 项目。
将自定义 activity 添加到您的 Unity 引擎项目
插件包中的 Assets/Plugins/Android/VkQualityTestActivity.java
包含一个使用 VkQuality 的自定义 activity 示例。要自定义文件并在游戏中使用它,请执行以下步骤
- 将
VkQualityTestActivity.java
文件复制到您的Assets/Plugins/Android
目录。 - 将其重命名为适合您的游戏的名称(例如,
MyGameActivity.java
)。 - 在文本编辑器中打开文件。
- 将类名从
VkQualityTestActivity
更改为您给文件的名称(例如,MyGameActivity.java
)。 - 将包名从
com.google.android.games.VkQualityTest
更改为与 Unity 项目设置 Player 类别下 Other Settings 中的 Package Name 字段的值匹配(例如,com.mycompany.mygame
)。 - 保存并关闭文件。
添加一个引用您的自定义 activity 的自定义清单文件,并告诉 Unity 使用您的自定义清单文件
- 将插件包
Assets/Plugins/Android
目录中的AndroidManifest.xml
文件复制到您项目的Asset/Plugins/Android
目录。 - 在文本编辑器中打开文件。
- 将
activity android:name
设置的值从com.google.android.games.VkQualityTest.VkQualityTestActivity
更改为上一步中使用的包名和 activity 名(例如,com.mycompany.mygame.MyGameActivity
)。 - 保存并关闭文件。
- 打开 Unity 设置窗口并选择 Player 设置。展开 Publishing Settings 部分,并选中 Custom Main Manifest 复选框。

您的项目现在已设置为使用在启动时调用 VkQuality 并根据 VkQuality 推荐选择 Vulkan 或 OpenGL ES 的自定义 activity。
将 VkQuality 添加到现有自定义 activity
如果您的游戏已经有一个自定义 activity 覆盖了默认的 UnityPlayerActivity
,请通过添加以下代码来集成 VkQuality 推荐
首先,将 VkQuality 导入语句添加到自定义 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,并根据 VkQuality 推荐选择 Vulkan 或 OpenGL 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
枚举值。
要创建自定义推荐列表文件,请使用位于 GitHub 仓库中的 VkQuality List Editor 工具。该工具的文档位于其 README 中。