Unity 引擎的 VkQuality 外掛程式會提供圖形 API (Vulkan 或 OpenGL ES) 的啟動時間建議,以便用於特定裝置上的遊戲。
VkQuality 針對 Vulkan 建議在比 Unity 引擎預設許可清單上更受限制的裝置組合。使用 VkQuality 可獲得 Vulkan 的效能優勢,同時只能在搭載較新版圖形驅動程式的新型裝置上使用 Vulkan,這將限制遊戲暴露於驅動程式的問題。VkQuality 只會提供品質建議,而非保證,因為在推薦裝置上仍有駕駛問題。VkQuality 支援自訂清單,可讓您為遊戲新增或移除裝置建議。
在 Unity 引擎遊戲中啟用 Vulkan
如要使用 VkQuality,遊戲必須在 Unity 專案設定中同時啟用 OpenGL ES 和 Vulkan 轉譯器。使用 Auto Graphics 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 級別等於或高於建議清單中的 Future API 級別,VkQuality 會建議使用 Vulkan。預設的推薦清單的 Future 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 外掛程式是位於已下載套件封存檔 Assets/Android/Plugins
目錄中的 VkQuality-1.x.x.aar
檔案。.aar 檔案的實際版本號碼與套件封存名稱的版本編號相符。如要安裝外掛程式,請按照下列步驟操作:
- 將 .aar 檔案複製到專案的
Assets/Android/Plugins
目錄。(如果所需的Android
和Plugins
子目錄不存在,請建立這些子目錄)。
![必要專案目錄中的 VkQuality .aar 檔案。](https://developer.android.google.cn/static/images/games/engines/unity/unity-vkquality-unityassets.png?hl=zh-tw)
- 在 Unity 的「Project」階層中選取
VkQuality-1.x.x
外掛程式檔案,在「Inspector」窗格中顯示其「Import Settings」。確認已勾選「Android」平台。
![圖 2. VkQuality 外掛程式平台匯入設定。](https://developer.android.google.cn/static/images/games/engines/unity/unity-vkquality-unityplugin.png?hl=zh-tw)
使用自訂活動呼叫 VkQuality
與一般 Unity 引擎外掛程式不同,必須在 Unity 引擎初始化之前執行 VkQuality,以取得圖形 API 建議。然後使用 Unity 播放器指令列引數功能,根據 VkQuality 建議設定 Graphs API。在 Android 中,傳遞指令列引數時,必須透過建立自訂活動,覆寫 UnityPlayerActivity 的預設行為。
如果遊戲已在使用自訂活動,請參閱「將 VkQuality 新增至現有自訂活動」一節。如要為遊戲建立新的自訂活動,請參閱下文的「在 Unity 專案中新增自訂活動」。
將自訂活動新增至 Unity 引擎專案
Assets/Plugins/Android/VkQualityTestActivity.java
的外掛程式套件內含使用 VkQuality 的自訂活動範例。如要自訂檔案並用於遊戲,請按照下列步驟操作:
- 將
VkQualityTestActivity.java
檔案複製到Assets/Plugins/Android
目錄。 - 將其重新命名為適合遊戲的名稱 (例如
MyGameActivity.java
)。 - 使用文字編輯器開啟檔案。
- 將類別名稱從
VkQualityTestActivity
變更為您提供的檔案名稱 (例如MyGameActivity.java
)。 - 將套件名稱從
com.google.android.games.VkQualityTest
變更為符合 Unity 專案設定「Player」類別中的「Package Name」欄位值 (例如com.mycompany.mygame
)。 - 儲存並關閉檔案。
新增參照自訂活動的自訂資訊清單檔案,並指示 Unity 使用您的自訂資訊清單檔案:
- 將外掛程式套件的
Assets/Plugins/Android
目錄中的AndroidManifest.xml
檔案複製到專案的Asset/Plugins/Android
目錄中。 - 使用文字編輯器開啟檔案。
- 將
activity android:name
設定的值從com.google.android.games.VkQualityTest.VkQualityTestActivity
變更為您在先前步驟中使用的套件和活動名稱 (例如com.mycompany.mygame.MyGameActivity
)。 - 儲存並關閉檔案。
- 開啟 Unity 設定視窗,然後選取「Player」設定。展開「Publishing Settings」(發布設定) 部分,然後勾選「Custom Main Manifest」(自訂主要資訊清單) 核取方塊。
![圖 3:Unity Player 設定中的「自訂主要資訊清單」選項。](https://developer.android.google.cn/static/images/games/engines/unity/unity-vkquality-unitymanifest.png?hl=zh-tw)
您的專案現在已設定為使用在啟動時呼叫 VkQuality 的自訂活動,並根據 VkQuality 建議選擇 Vulkan 或 OpenGL ES。
將 VkQuality 新增至現有自訂活動
如果遊戲已有自訂活動覆寫預設的 UnityPlayerActivity
,請加入下列程式碼來整合 VkQuality 建議:
首先,將 VkQuality 匯入陳述式新增至自訂活動檔案頂端的匯入清單:
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; }
您的自訂活動現在會在啟動時呼叫 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 中。