افزایه موتور VkQuality Unity

افزونه VkQuality برای موتور Unity توصیه‌هایی برای زمان راه‌اندازی میانای برنامه‌سازی کاربردی گرافیک (Vulkan یا OpenGL ES) ارائه می‌دهد تا از آن برای بازی‌تان در دستگاه‌های خاص استفاده کنید.

VkQuality Vulkan را در مجموعه محدودتری از دستگاه‌ها نسبت‌به فهرست مجاز پیش‌فرض موتور Unity توصیه می‌کند. از VkQuality استفاده کنید تا از مزایای عملکرد Vulkan بهره‌مند شوید و درعین‌حال استفاده از Vulkan را به دستگاه‌های جدیدتر با درایورهای گرافیک جدیدتر محدود کنید، که این کار مواجهه بازی شما با مشکلات درایور را محدود می‌کند. VkQuality فقط توصیه‌های کیفی ارائه می‌دهد و تضمینی نمی‌کند، زیرا هنوز ممکن است در دستگاه‌های توصیه‌شده با مشکلات درایور مواجه شوید. VkQuality از فهرست‌های سفارشی پشتیبانی می‌کند، که به شما امکان می‌دهد توصیه‌های دستگاه را برای بازی‌تان اضافه یا حذف کنید.

فعال کردن Vulkan در بازی موتور Unity

VkQuality مستلزم این است که بازی شما هم پردازنده OpenGL ES و هم پردازنده Vulkan را در تنظیمات پروژه Unity فعال کرده باشد. پردازنده گرافیکی را بااستفاده از گزینه Auto Graphics API یا با تنظیم دستی میاناهای برنامه‌سازی کاربردی گرافیک فعال کنید.

دریافت افزایه VkQuality برای موتور Unity

افزونه VkQuality را از GitHub بارگیری کنید. این افزایه با Unity 2021 و بالاتر سازگار است. برای فعال کردن Vulkan در Android، از Unity 2021 LTS یا بالاتر استفاده کنید. بسته افزایه حاوی پروژه نمونه پایه‌ای است که از افزایه برای تنظیم کردن میانای برنامه‌سازی کاربردی گرافیک در زمان راه‌اندازی استفاده می‌کند و سپس رشته‌ای را که برای میانای برنامه‌سازی کاربردی گرافیک فعال دستگاه تنظیم شده است نمایش می‌دهد.

مدیریت فهرست توصیه‌های Vulkan در VkQuality

VkQuality شامل فهرست توصیه‌های پیش‌فرض دستگاه‌های پشتیبانی‌شده است. برای اطلاعات بیشتر درباره استفاده از فهرست توصیه‌های سفارشی، به بخش استفاده از فهرست توصیه‌های سفارشی مراجعه کنید.

فهرست توصیه‌ها شامل سه دسته است:

  • فهرست مجاز دستگاه Vulkan
  • فهرست مجاز توصیه‌های GPU
  • فهرست رد کردن توصیه GPU

مطابقت‌های فهرست مجاز دستگاه

VkQuality ابتدا بررسی می‌کند که آیا دستگاه فعال در فهرست مجاز دستگاه‌ها قرار دارد یا نه، و آیا حداقل نسخه Android و نسخه Vulkan driver مشخص‌شده در فهرست مجاز برای آن دستگاه را اجرا می‌کند یا نه. اگر این معیارها برآورده شود، VkQuality با برگرداندن مقدار شمارشی RECOMMENDATION_VULKAN_BECAUSE_DEVICE_MATCH، Vulkan را توصیه می‌کند.

اگر دستگاه در فهرست مجاز باشد، اما نسخه Android یا نسخه درایور آن پایین‌تر از حداقل مشخص‌شده برای آن در فهرست مجاز باشد، VkQuality با برگرداندن RECOMMENDATION_GLES_BECAUSE_OLD_DRIVER،‏ OpenGL ES را توصیه می‌کند.

توصیه GPU مطابقت دارد

اگر هیچ دستگاه منطبقی در فهرست مجاز دستگاه‌ها پیدا نشود، VkQuality مدل واحد پردازش گرافیکی و نسخه درایور را با فهرست‌های مجاز و غیرمجاز توصیه‌شده برای واحد پردازش گرافیکی ارزیابی می‌کند. اگر مدل واحد پردازش گرافیکی و نسخه درایور با ورودی‌ای در فهرست مجاز توصیه‌شده واحد پردازش گرافیکی مطابقت داشته باشد، VkQuality با برگرداندن ثابت شمارشی RECOMMENDATION_VULKAN_BECAUSE_PREDICTION_MATCH، Vulkan را توصیه می‌کند.

اگر مدل GPU و نسخه درایور با ورودی‌ای در فهرست رد توصیه‌های GPU مطابقت داشته باشد، VkQuality با برگرداندن RECOMMENDATION_GLES_BECAUSE_PREDICTION_MATCH،‏ OpenGL ES را توصیه می‌کند.

توصیه‌های بدون تطابق

اگر هیچ موردی پیدا نشد، VkQuality درصورتی Vulkan را توصیه می‌کند که سطح میانای برنامه‌سازی کاربردی Android دستگاه درحال اجرا برابر یا بالاتر از سطح میانای برنامه‌سازی کاربردی Future در فهرست توصیه‌ها باشد. فهرست توصیه‌های پیش‌فرض دارای سطح میانای برنامه‌سازی کاربردی آینده ۳۶ است، یعنی در دستگاه‌های نامطابق که سطح میانای برنامه‌سازی کاربردی ۳۶ یا بالاتر را اجرا می‌کنند، VkQuality ثابت شمارشی RECOMMENDATION_VULKAN_BECAUSE_FUTURE_ANDROID را برمی‌گرداند.

اگر هیچ موردی در فهرست مجاز دستگاه یا فهرست‌های توصیه‌شده GPU پیدا نشود، و سطح API دستگاه پایین‌تر از سطح 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 پروژه‌تان کپی کنید. (زیرفهرست‌های راهنمای Android و Plugins موردنیاز را اگر وجود ندارند ایجاد کنید.)
فایل VkQuality .aar در دایرکتوری پروژه موردنیاز.
شکل ۱.فایل VkQuality .aar در دایرکتوری پروژه موردنیاز.
  1. فایل افزایه VkQuality-1.x.x را در سلسله‌مراتب پروژه Unity انتخاب کنید تا تنظیمات وارد کردن آن در قاب بازرس نمایش داده شود. مطمئن شوید پلاتفرم Android علامت زده شده باشد.
شکل ۲.‏ تنظیمات وارد کردن پلاتفرم افزایه VkQuality.
شکل ۲. تنظیمات وارد کردن پلاتفرم افزایه VkQuality.

استفاده از فعالیت سفارشی برای فراخوانی VkQuality

برخلاف افزایه‌های معمولی موتور Unity، برای دریافت توصیه میانای برنامه‌سازی کاربردی گرافیک، VkQuality باید قبل‌از مقداردهی اولیه موتور Unity اجرا شود. سپس از ویژگی آرگومان‌های خط فرمان پخش‌کننده Unity برای تنظیم میانای برنامه‌سازی کاربردی گرافیک براساس توصیه VkQuality استفاده می‌کنید. در Android، ارسال متغیرهای مستقل خط فرمان مستلزم لغو رفتار پیش‌فرض UnityPlayerActivity با ایجاد یک فعالیت سفارشی است.

اگر بازی شما ازقبل از فعالیت سفارشی استفاده می‌کند، به بخش افزودن VkQuality به فعالیت سفارشی موجود مراجعه کنید. برای ایجاد فعالیت سفارشی جدید برای بازی‌تان، به افزودن فعالیت سفارشی به پروژه Unity در ادامه مراجعه کنید.

افزودن فعالیت سفارشی به پروژه موتور Unity

یک فعالیت سفارشی نمونه که از VkQuality استفاده می‌کند در بسته افزونه در 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» شما مطابقت داشته باشد (برای مثال، com.mycompany.mygame).
  6. فایل را ذخیره کنید و ببندید.

فایل مانیفست سفارشی‌ای اضافه کنید که به فعالیت سفارشی‌تان ارجاع دهد و به Unity بگویید از فایل مانیفست سفارشی‌تان استفاده کند:

  1. فایل AndroidManifest.xml را از فهرست راهنمای Assets/Plugins/Android بسته افزونه در فهرست راهنمای Asset/Plugins/Android پروژه‌تان کپی کنید.
  2. فایل را در ویرایشگر نوشتار باز کنید.
  3. مقدار تنظیم activity android:name را از com.google.android.games.VkQualityTest.VkQualityTestActivity به نام‌های بسته و فعالیتی که در مراحل قبلی استفاده کردید تغییر دهید (برای مثال، com.mycompany.mygame.MyGameActivity).
  4. فایل را ذخیره کنید و ببندید.
  5. پنجره تنظیمات Unity را باز کنید و تنظیمات پخش‌کننده را انتخاب کنید. بخش تنظیمات انتشار را ازهم باز کنید و چارگوش انتخاب مانیفست اصلی سفارشی را علامت بزنید.
شکل ۳.گزینه Custom Main Manifest (مانیفست اصلی سفارشی) در تنظیمات Unity Player.
شکل ۳.گزینه مانیفست اصلی سفارشی در تنظیمات پخش‌کننده Unity.

اکنون پروژه شما برای استفاده از فعالیت سفارشی‌ای که VkQuality را در زمان راه‌اندازی فراخوانی می‌کند و Vulkan یا OpenGL ES را براساس توصیه VkQuality انتخاب می‌کند راه‌اندازی شده است.

افزودن VkQuality به فعالیت سفارشی موجود

اگر بازی‌تان ازقبل فعالیت سفارشی‌ای دارد که UnityPlayerActivity پیش‌فرض را لغو می‌کند، توصیه‌های VkQuality را با افزودن کد زیر ادغام کنید:

ابتدا، عبارت وارد کردن VkQuality را به فهرست وارد کردن‌ها در بالای فایل فعالیت سفارشی اضافه کنید:

کاتلین

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

جاوا

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

سپس، چند ثابت در بدنه کلاس Activity برای انتخاب‌های میانای برنامه‌سازی کاربردی گرافیک ایجاد کنید:

کاتلین

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

جاوا

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

متغیری برای ردیابی انتخاب میانای برنامه‌سازی کاربردی ایجاد کنید:

کاتلین

private var apiOverride = OVERRIDE_NONE

جاوا

private int apiOverride = OVERRIDE_NONE;

تابع زیر را به کلاس Activity اضافه کنید:

کاتلین

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")
    }
}

جاوا

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

تابع CheckVkQuality را از بالای تابع لغو onCreate() فراخوانی کنید، قبل‌از اینکه پیاده‌سازی کلاس پایه را فراخوانی کنید:

کاتلین

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

جاوا

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

درنهایت، یک لغو برای تابع updateUnityCommandLineArguments() اضافه کنید که از مقدار apiOverride برای ارسال آرگومان خط فرمان به موتور Unity استفاده می‌کند و مشخص می‌کند که از کدام Graphics API استفاده شود:

کاتلین

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

جاوا

@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 را در راه‌اندازی فراخوانی می‌کند و Vulkan یا OpenGL ES را براساس توصیه VkQuality انتخاب می‌کند.

استفاده از فهرست توصیه‌های سفارشی

با ارسال نام فایل حاوی فهرست به StartVkQuality() به‌جای ارسال رشته خالی، فایل فهرست توصیه سفارشی را مشخص کنید:

کاتلین

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

جاوا

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

‫VkQuality ابتدا فایل را در دایرکتوری حافظه داخلی برنامه‌تان جستجو می‌کند. اگر فایل در حافظه داخلی نباشد، VkQuality سعی می‌کند فایل را از دارایی‌های دسته برنامه‌تان بار کند. اگر فایل در هیچ‌کدام از این مکان‌ها نباشد، VkQuality مقدار شمارشی ERROR_MISSING_DATA_FILE را برمی‌گرداند.

برای ایجاد فایل فهرست توصیه‌های سفارشی، از ابزار ویرایشگر فهرست VkQuality واقع در مخزن GitHub استفاده کنید. اسناد مربوط به این ابزار در README آن قرار دارد.