کوچک کردن و بهینه‌سازی کد Unity با R8

اگرچه منطق اصلی بازی شما در Unity به زبان C#‎ نوشته شده است (با IL2CPP کامپایل شده است)، ساخت‌های Android شامل بایت‌کد قابل‌توجهی از Java و Kotlin (classes.dex) برای مدیریت رویدادهای چرخه حیات UnityPlayerActivity، خدمات Google Play، صورت‌حساب، تبلیغات، و کیت‌های توسعه نرم‌افزار اجتماعی است.

فعال کردن R8، بهینه‌ساز و کوچک‌کننده کد پیش‌فرض در افزونه Android Gradle (AGP)، کلاس‌ها و روش‌های استفاده‌نشده را حذف می‌کند و بایت‌کد را بهینه‌سازی می‌کند. این کار نه تنها اندازه بارگیری برنامه‌تان را کاهش می‌دهد، بلکه ردپای حافظه زمان اجرا صفحه‌های DEX نگاشت‌شده در حافظه (mmap) و سربار فرایند Java پایه را نیز کاهش می‌دهد، فشار حافظه فیزیکی را کاهش می‌دهد، و از توقف‌های ناشی از بستن ناشی از کمبود حافظه (LMK) جلوگیری می‌کند. Google Play همچنین سطوح بهینه‌سازی DEX بازی‌تان را ازطریق سنجه بهینه‌سازی کد DEX در «معیارهای کلیدی Android» پایش می‌کند.

رفتار پیش‌فرض و پشتیبانی از نسخه Unity

در Unity، کوچک‌سازی کد به‌طور پیش‌فرض (false) برای هر دو ساخت «انتشار» و «اشکال‌زدایی» هنگام ایجاد پروژه جدید غیرفعال است.

Unity برای اولین‌بار R8 را به‌عنوان کلید اختیاری در Unity 2020.1.0f1 معرفی کرد. از Unity 2022.2.0f1 (و با انتقال به Unity 2021.3.41f1 LTS)، Unity زنجیره ابزار بسته‌ای خود را به AGP 7.1.2+ ارتقا داد، پشتیبانی ProGuard قدیمی را حذف کرد، و هر زمان که کوچک‌سازی فعال باشد، منحصراً R8 را اجرا می‌کند.

نسخه Unity AGP بسته‌ای پیش‌فرض نسخه پخش پشتیبانی R8 و پیکربندی لازم
‫2019.4 LTS و نسخه‌های قدیمی‌تر قدیمی‌تر از نسخه ۳.۴ غیرفعال (false) پشتیبانی نمی‌شود (فقط ProGuard قدیمی).
2020.1.0f1 تا 2021.3.40f1 ‫۳٫۴ تا ۴٫۰ غیرفعال (false) اختیاری (به‌طور پیش‌فرض ProGuard). هر دو گزینه Minify > Release و Use R8 را فعال کنید.
2021.3.41f1 و بالاتر (2021 LTS) 7.1+‎ غیرفعال (false) فقط R8. Minify > Release را فعال کنید تا R8 به‌طور خودکار اجرا شود.
‫2022.2.0f1 تا Unity 6+ ‫۷.۱ تا ۸.x غیرفعال (false) فقط R8. Minify > Release را فعال کنید تا R8 به‌طور خودکار اجرا شود.

فعال کردن R8 در «تنظیمات پخش‌کننده»

برای فعال کردن کوچک کردن کد R8 و بهینه‌سازی برای ساخت‌های «نسخه پخش»:

  1. در Unity Editor، ویرایش > تنظیمات پروژه را باز کنید و پخش‌کننده را انتخاب کنید.
  2. برگه Android را انتخاب کنید و تنظیمات انتشار > ساخت را ازهم باز کنید.
  3. در بخش Minify، گزینه‌های مربوط به نسخه Unity خود را پیکربندی کنید:
    • Unity 2021.3.41f1+‎ و 2022.2.0f1+‎: انتشار را انتخاب کنید. Unity به‌طور خودکار R8 را درطول تکلیف Gradle minifyReleaseWithR8 اجرا می‌کند.
    • Unity 2020.1.0f1 تا 2021.3.40f1: هم Release و هم Use R8 را انتخاب کنید.

اگر بااستفاده از دستورگان «ویرایشگر C# ‎» ساخت‌ها را خودکار می‌کنید، این ویژگی‌ها را ازطریق PlayerSettings.Android پیکربندی کنید:

using UnityEditor;

public static class AndroidBuildConfig
{
    public static void EnableR8ForRelease()
    {
        PlayerSettings.Android.minifyRelease = true;

        // Required only in Unity 2020.1.0f1 to 2021.3.40f1 and 2022.1 or earlier
        // (In Unity 2021.3.41f1+ and 2022.2+, R8 is always used when minification is enabled)
#if !UNITY_2022_2_OR_NEWER
        PlayerSettings.Android.minifyWithR8 = true;
#endif
    }
}

افزودن قوانین حفظ برای JNI و بازتاب

کلاس‌ها و روش‌های جاوا که به‌طور پویا از اسکریپت‌های C# ‎ بااستفاده از AndroidJavaClass یا AndroidJavaObject فراخوانی می‌شوند، سایت‌های فراخوانی جاوای ایستا ندارند. بدون قوانین صریح نگهداری، R8 ممکن است این کلاس‌ها را بلااستفاده درنظر بگیرد و آن‌ها را حذف کند یا نامشان را تغییر دهد.

برای حفظ پل‌های Java سفارشی:

  1. در تنظیمات پروژه > پخش‌کننده > Android > تنظیمات انتشار > ساخت، فایل Proguard سفارشی را فعال کنید.
  2. فایل Assets/Plugins/Android/proguard-user.txt تولیدشده را باز کنید.
  3. افزودن قوانین -keep برای کلاس‌هایی که ازطریق JNI به آن‌ها دسترسی پیدا شده است یا افزایه‌های شخص ثالث به آن‌ها نیاز دارند:
# Keep custom Java classes invoked from C# using JNI bridges
-keep class com.example.yourgame.** { *; }

# Keep callback interfaces passed between C# and Java
-keep interface com.example.yourgame.IPluginCallback { *; }

عیب‌یابی کردن مسائل رایج

این بخش نحوه حل مشکلات رایج ساخت و زمان اجرا را هنگام استفاده از R8 در Unity شرح می‌دهد.

‫Missing classes detected while running R8 خطای ساخت

در نسخه‌های Unity که از AGP نسخه ۷.۰ و بالاتر (‎2021.3.41f1+‎ و ‎2022.2+‎) استفاده می‌کنند، R8 بررسی‌های سخت‌گیرانه‌ای برای کلاس‌های مفقودشده اعمال می‌کند. اگر ساخت با این خطا ناموفق بود، فایل missing_rules.txt تولیدشده را در فهرست راهنمای خروجی ساخت (زیر Library/Bee/Android/Prj/.../build/outputs/mapping/release/missing_rules.txt یا Temp/gradleOut/...) بررسی کنید و وابستگی‌ها یا قوانین لازم را به proguard-user.txt اضافه کنید. برای اطلاعات بیشتر درباره نوشتن قوانین نگهداری، به سفارشی‌سازی کد برای نگهداری مراجعه کنید.

سازگاری حالت کامل R8 با افزایه‌های طرف سوم

در AGP نسخه ۸.۰ و بالاتر (Unity 6+)، حالت کامل R8 به‌طور پیش‌فرض فعال است تا بهینه‌سازی‌های تهاجمی‌تری انجام شود. اگر افزایه Android قدیمی در زمان اجرا به‌دلیل مشکلات بازتابی ناموفق بود، قوانین ProGuard افزایه را به‌روز کنید یا R8 را به حالت سازگاری برگردانید:

  1. در Publishing Settings (تنظیمات انتشار) > Build (ساخت)، Custom Gradle Properties Template (الگوی ویژگی‌های Gradle سفارشی) را فعال کنید.
  2. Assets/Plugins/Android/gradleTemplate.properties را باز کنید و ویژگی زیر را اضافه کنید:
android.enableR8.fullMode=false