适用于 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 文件的版本号与软件包的版本号一致
归档名称。如需安装该插件,请执行以下步骤:
- 将该 .aar 文件复制到您的
Assets/Android/Plugins
项目。(创建所需的Android
和Plugins
子目录,如果需要 不存在。)
- 在 Unity Project 层次结构中选择
VkQuality-1.x.x
插件文件 在 Inspector 窗格中打开 Import Settings。请确保 已选中 Android 平台。
使用自定义 activity 调用 VkQuality
与典型的 Unity 引擎插件不同,必须执行 VkQuality 才能获得 图形 API 建议。然后,您可以使用 Unity 播放器命令行参数功能来设置 根据 VkQuality 建议生成的图形 API。在 Android 上,传递 命令行参数要求覆盖 UnityPlayerActivity创建一个自定义 activity。
如果您的游戏已在使用自定义 activity,请参阅将 VkQuality 添加到 现有自定义活动部分。要创建新的自定义活动,请执行以下操作: 请参阅下一部分中的向 Unity 项目添加自定义 activity。
向 Unity 引擎项目添加自定义 activity
插件中包含使用 VkQuality 的自定义 Activity 示例
软件包位于 Assets/Plugins/Android/VkQualityTestActivity.java
中。
如需自定义该文件并在游戏中使用,请按以下步骤操作:
- 将
VkQualityTestActivity.java
文件复制到Assets/Plugins/Android
目录中。 - 将其重命名为适合您游戏的名称(例如,
MyGameActivity.java
)。 - 在文本编辑器中打开该文件。
- 将类名称从
VkQualityTestActivity
更改为您为 文件(例如MyGameActivity.java
)。 - 将软件包名称从
com.google.android.games.VkQualityTest
更改为 与 Unity Project 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 建议选择 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 文件。