R8 की मदद से, Unity कोड को छोटा और ऑप्टिमाइज़ करना

Unity में आपके गेम का मुख्य लॉजिक C# में लिखा गया है (IL2CPP के साथ कंपाइल किया गया है). हालांकि, Android बिल्ड में काफ़ी Java और Kotlin बाइट कोड (classes.dex) शामिल होता है. इससे UnityPlayerActivity लाइफ़साइकल इवेंट, Google Play services, बिलिंग, विज्ञापन, और सोशल एसडीके मैनेज किए जाते हैं.

Android Gradle प्लगिन (AGP) में, कोड को छोटा और ऑप्टिमाइज़ करने वाले डिफ़ॉल्ट टूल R8 को चालू करने पर, इस्तेमाल न होने वाली क्लास और तरीके हट जाते हैं. साथ ही, बाइट कोड ऑप्टिमाइज़ हो जाता है. इससे न सिर्फ़ आपके ऐप्लिकेशन का डाउनलोड साइज़ कम होता है, बल्कि मेमोरी-मैप किए गए (mmap) DEX पेजों और बेसलाइन Java प्रोसेस ओवरहेड के रनटाइम मेमोरी फ़ुटप्रिंट भी कम होते हैं. इससे फ़िज़िकल मेमोरी का दबाव कम होता है और लो मेमोरी किलर (एलएमके) की वजह से ऐप्लिकेशन बंद होने की समस्या कम होती है. Google Play, Android की ज़रूरी जानकारी में मौजूद DEX कोड ऑप्टिमाइज़ेशन मेट्रिक की मदद से, आपके गेम के DEX ऑप्टिमाइज़ेशन लेवल पर भी नज़र रखता है.

डिफ़ॉल्ट ऐक्शन और सेटिंग और Unity वर्शन के साथ काम करने की सुविधा

Unity में, नया प्रोजेक्ट बनाते समय रिलीज़ और डीबग के लिए बिल्ड, दोनों के लिए कोड की काट-छांट करने की सुविधा डिफ़ॉल्ट रूप से बंद (false) होती है.

Unity ने सबसे पहले Unity 2020.1.0f1 में, R8 को एक वैकल्पिक टॉगल के तौर पर पेश किया था. Unity 2022.2.0f1 (और Unity 2021.3.41f1 एलटीएस पर बैकपोर्ट किया गया) से, Unity ने अपने बंडल किए गए टूल चेन को AGP 7.1.2+ पर अपग्रेड कर दिया है. साथ ही, ProGuard के लेगसी वर्शन के लिए सहायता हटा दी है. इसके अलावा, काट-छांट की सुविधा चालू होने पर, सिर्फ़ R8 को चलाया जाता है.

Unity का वर्शन बंडल किया गया एजीपी रिलीज़ का डिफ़ॉल्ट तरीका R8 की सुविधा और ज़रूरी कॉन्फ़िगरेशन
2019.4 एलटीएस और इससे पहले के वर्शन 3.4 से पहले के वर्शन बंद है (false) इस्तेमाल नहीं किया जा सकता (सिर्फ़ लेगसी ProGuard के लिए).
2020.1.0f1 से 2021.3.40f1 3.4 से 4.0 बंद है (false) ज़रूरी नहीं है (डिफ़ॉल्ट रूप से ProGuard पर सेट होता है). Minify > Release और Use R8, दोनों को चालू करें.
2021.3.41f1 और इसके बाद के वर्शन (2021 LTS) 7.1+ बंद है (false) सिर्फ़ R8. R8 को अपने-आप चलने की अनुमति देने के लिए, Minify > Release को चालू करें.
2022.2.0f1 से Unity 6+ 7.1 से 8.x बंद है (false) सिर्फ़ R8. R8 को अपने-आप चलने की अनुमति देने के लिए, Minify > Release को चालू करें.

प्लेयर की सेटिंग में जाकर R8 को चालू करना

रिलीज़ के लिए तैयार बिल्ड के लिए, R8 की मदद से कोड छोटा करने और ऑप्टिमाइज़ करने की सुविधा चालू करने के लिए:

  1. Unity Editor में, Edit > Project Settings खोलें और Player को चुनें.
  2. Android टैब को चुनें और Publishing Settings > Build को बड़ा करें.
  3. Minify सेक्शन में जाकर, Unity के अपने वर्शन के लिए विकल्प कॉन्फ़िगर करें:
    • Unity 2021.3.41f1+ और 2022.2.0f1+: Release को चुनें. Unity, minifyReleaseWithR8 Gradle टास्क के दौरान R8 को अपने-आप चलाता है.
    • 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
    }
}

जेएनआई और रिफ़्लेक्शन के लिए, 'keep' नियम जोड़ना

AndroidJavaClass या AndroidJavaObject का इस्तेमाल करके, C# स्क्रिप्ट से डाइनैमिक तौर पर शुरू की गई Java क्लास और मेथड में, कोई स्टैटिक Java कॉल साइट नहीं होती. अगर साफ़ तौर पर 'keep' नियम नहीं दिए जाते हैं, तो हो सकता है कि R8 इन क्लास को इस्तेमाल न की गई क्लास मान ले और उन्हें हटा दे या उनका नाम बदल दे.

अपने कस्टम Java ब्रिज को सुरक्षित रखने के लिए:

  1. प्रोजेक्ट सेटिंग > Player > Android > Publishing Settings > Build में जाकर, Custom Proguard File को चालू करें.
  2. जनरेट की गई Assets/Plugins/Android/proguard-user.txt फ़ाइल खोलें.
  3. जेएनआई के ज़रिए ऐक्सेस की गई या तीसरे पक्ष के प्लग इन के लिए ज़रूरी क्लास के लिए, -keep नियम जोड़ें:
# 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 { *; }

अक्सर होने वाली समस्याएं हल करना

इस सेक्शन में, Unity में R8 का इस्तेमाल करते समय, बिल्ड और रनटाइम से जुड़ी सामान्य समस्याओं को हल करने का तरीका बताया गया है.

Missing classes detected while running R8 बिल्ड से जुड़ी गड़बड़ियां

AGP 7.0 और इसके बाद के वर्शन (2021.3.41f1+ और 2022.2+) का इस्तेमाल करने वाले Unity वर्शन में, R8 क्लास मौजूद न होने की जांच सख्ती से करता है. अगर कोई बिल्ड इस गड़बड़ी की वजह से फ़ेल हो जाता है, तो अपनी बिल्ड आउटपुट डायरेक्ट्री (Library/Bee/Android/Prj/.../build/outputs/mapping/release/missing_rules.txt या Temp/gradleOut/... में) में जनरेट की गई missing_rules.txt फ़ाइल की जांच करें. साथ ही, proguard-user.txt में ज़रूरी डिपेंडेंसी या नियम जोड़ें. कोड को बनाए रखने के नियम लिखने के बारे में ज़्यादा जानने के लिए, तय करें कि कौनसा कोड बनाए रखना है लेख पढ़ें.

तीसरे पक्ष के प्लग इन के साथ R8 फ़ुल मोड की कंपैटिबिलिटी

AGP 8.0 और इसके बाद के वर्शन (Unity 6+) में, R8 फ़ुल मोड डिफ़ॉल्ट रूप से चालू होता है, ताकि ज़्यादा बेहतर तरीके से ऑप्टिमाइज़ेशन किया जा सके. अगर रिफ़्लेक्शन से जुड़ी समस्याओं की वजह से, कोई लेगसी Android प्लगिन रनटाइम के दौरान काम नहीं करता है, तो प्लगिन के ProGuard नियमों को अपडेट करें या R8 को कंपैटिबिलिटी मोड पर वापस लाएं:

  1. Publishing Settings > Build में जाकर, Custom Gradle Properties Template को चालू करें.
  2. Assets/Plugins/Android/gradleTemplate.properties खोलें और यह प्रॉपर्टी जोड़ें:
android.enableR8.fullMode=false