Rút gọn và tối ưu hoá mã Unreal Engine bằng R8

Mặc dù logic trò chơi cốt lõi của bạn trong Unreal Engine được viết bằng C++ hoặc Blueprints, nhưng gói Android sẽ biên dịch mã byte Java và Kotlin (classes.dex) để xử lý các sự kiện trong vòng đời GameActivity, Dịch vụ Google Play, tính năng thanh toán, âm thanh và trình bổ trợ phân tích.

R8, trình tối ưu hoá và rút gọn mã mặc định trong Trình bổ trợ Android cho Gradle (AGP), sẽ xoá các lớp và phương thức không dùng đến, đồng thời tối ưu hoá mã byte. Điều này không chỉ giảm kích thước tải xuống của gói mà còn giảm mức sử dụng bộ nhớ trong thời gian chạy của các trang DEX được ánh xạ bộ nhớ (mmap) và mức hao tổn của quy trình Java cơ sở, giảm áp lực bộ nhớ vật lý và các trường hợp chấm dứt do trình chấm dứt ứng dụng khi bộ nhớ thấp (LMK). Google Play cũng giám sát mức độ tối ưu hoá DEX của trò chơi thông qua chỉ số Tối ưu hoá mã DEX trong Android vitals.

Hành vi mặc định và hỗ trợ phiên bản Unreal Engine

Kể từ UE 4.22.0, UEDeployAndroid.cs của Unreal Engine sẽ chèn minifyEnabled true vào cấu hình bản dựng bản phát hành Android đã tạo (buildAdditions.gradle) theo mặc định. Vì UE 4.25 đã nâng cấp chuỗi công cụ đi kèm lên AGP 4.0.0, nên R8 được bật theo mặc định (true) trên tất cả bản dựng Phát hành (Vận chuyển và Phân phối) trong UE 4.25 trở lên mà không cần thiết lập thêm.

Phiên bản Unreal Engine AGP đi kèm Bản phát hành mặc định Gỡ lỗi mặc định Hành vi
UE 4.21 trở xuống Gradle hoặc Ant cũ Đã tắt (false) Đã tắt (false) Không có cấu hình minifyEnabled nào được công cụ chèn vào.
UE 4.22 đến 4.24 Trước phiên bản 3.4 Đã bật (ProGuard) Đã tắt (false) minifyEnabled true được bật theo mặc định trong bản phát hành (chạy ProGuard).
UE 4.25 đến 5.3 4.0.0 Đã bật (R8) Đã tắt (false) Việc áp dụng AGP 4.0 sẽ chạy R8 theo mặc định trong các bản phát hành.
UE 5.4 đến 5.7 7.4.2 Đã bật (R8) Đã tắt (false) AGP 7.x xoá các tuỳ chọn useProguard cũ; R8 chạy độc quyền.
UE 5.8 (5.8.3 trở lên) 8.13.0 Đã bật (R8) Đã tắt (false) Sử dụng AGP 8.x và quy trình tối ưu hoá R8 hiện đại theo mặc định.

Sự khác biệt giữa bản phát hành và bản gỡ lỗi

UnrealBuildTool (UEDeployAndroid.cs) định cấu hình tệp buildAdditions.gradle được tạo theo cách khác nhau cho bản dựng Phát hành và bản gỡ lỗi:

buildTypes {
    release {
        signingConfig signingConfigs.release
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
    debug {
        debuggable true
        signingConfig signingConfigs.debug
    }
}
  • Phát hành (Vận chuyển hoặc Phân phối): Đặt minifyEnabled true và áp dụng proguard-rules.pro theo mặc định, chạy tính năng rút gọn mã và làm rối mã R8.
  • Gỡ lỗi (Phát triển): Bật debuggable true và bỏ qua minifyEnabled (mặc định là false) để duy trì quá trình lặp lại bản dựng nhanh và gỡ lỗi ký hiệu.

Thêm quy tắc giữ lại bằng Ngôn ngữ trình bổ trợ Unreal (UPL)

Vì R8 tự động chạy trên các bản phát hành trong UE 4.25 trở lên, nên bạn phải giữ lại các lớp Java chỉ truy cập được thông qua JNI C++ (JNIEnv->FindClass, GetMethodID) hoặc tệp kê khai. Các lớp không có trang web gọi Java được coi là không sử dụng và bị R8 loại bỏ. Điều này có thể khiến các tính năng hoạt động trong bản dựng Phát triển không thành công với ClassNotFoundException hoặc NoSuchMethodError trong bản dựng Vận chuyển.

Sử dụng thẻ <proguardAdditions> trong tệp XML Unreal Plugin Language (UPL) để hợp nhất các quy tắc giữ lại tuỳ chỉnh vào proguard-rules.pro trong quá trình đóng gói. Thêm khối sau vào tệp *_UPL.xml của dự án hoặc trình bổ trợ:

<root xmlns:android="http://schemas.android.com/apk/res/android">
    <proguardAdditions>
        <insert>
            -keep class com.epicgames.unreal.** { *; }
            -keep class com.example.plugin.** { public *; }
            -dontwarn com.example.plugin.**
        </insert>
    </proguardAdditions>
</root>

Khắc phục các vấn đề thường gặp

Phần này mô tả cách giải quyết các vấn đề thường gặp về đóng gói và thời gian chạy khi sử dụng R8 trong Unreal Engine.

Tạm thời tắt R8 để gỡ lỗi

Để xác định xem sự cố chỉ xảy ra trong bản phát hành có phải do R8 loại bỏ các lớp bắt buộc hay không, hãy chèn DISABLE_MINIFY=1 vào dưới <gradleProperties> trong tệp UPL. Khi có mặt, UEDeployAndroid.cs sẽ tạo ra minifyEnabled false:

<gradleProperties>
    <insert>
        DISABLE_MINIFY=1
    </insert>
</gradleProperties>

Missing classes detected while running R8 lỗi đóng gói

Trong UE 5.4 trở lên (AGP 7.4.2 trở lên), R8 thực thi các quy trình kiểm tra nghiêm ngặt về lớp bị thiếu. Nếu gói không thành công do lỗi này, hãy kiểm tra missing_rules.txt trong thư mục bản dựng trung gian (trong Intermediate/Android/.../gradle/app/build/outputs/mapping/release/missing_rules.txt) rồi thêm các phần phụ thuộc thư viện bị thiếu hoặc quy tắc bắt buộc vào <proguardAdditions> trong tệp UPL.

Khả năng tương thích của chế độ đầy đủ R8 với SDK của bên thứ ba

Trong UE 5.8 trở lên (AGP 8.13.0 trở lên), chế độ đầy đủ của R8 được bật theo mặc định để thực hiện các hoạt động tối ưu hoá linh hoạt hơn. Nếu SDK Android cũ của bên thứ ba không hoạt động trong thời gian chạy do các vấn đề về phản chiếu, hãy cập nhật quy tắc ProGuard của trình bổ trợ hoặc đưa R8 về chế độ tương thích bằng cách thêm thuộc tính sau vào tệp UPL:

<gradleProperties>
    <insert>
        android.enableR8.fullMode=false
    </insert>
</gradleProperties>