• Home
  • /
  • UNITY
  • /
  • Gradle i Unity: poznaj plik konfiguracyjny mainTemplate [1/2]

Gradle i Unity: poznaj plik konfiguracyjny mainTemplate [1/2]

W tym wpisie przybliżę wam czym jest Gradle, jak wygląda plik konfiguracyjny oraz jak modyfikować go w projektach Unity. Przeczytaj jak sobie radzić z zależnościami oraz dodawaniem dodatkowych repozytoriów w pliku konfiguracyjnym i przekonaj się, że gradle nie taki straszny jak go malują 🙂

Czym jest Gradle?

Gradle jest uniwersalnym narzędziem do budowania aplikacji, pozwalającym, m.in zautomatyzować proces budowania, testowania oraz zarządzania zależnościami między projektami. Jest również, razem z Android Studio, oficjalnym narzędziem, dostarczanym i rozwijanym przez zespół Android SDK Tools.

Gradle pomaga zautomatyzować wiele procesów przy budowaniu również w Unity. Umożliwia zbudowanie projektu bezpośrednio z edytora Unity lub jego wyeksportowanie i następnie zbudowanie w zewnętrznym narzędziu (np. w Android Studio).

Korzyści zastosowania takiego systemu budowania można najszybciej zauważyć w projektach, które dodatkowo korzystają z narzędzia Play Services Resolver. Play Services Resolver jest pluginem, który zarządza zależnościami pojawiającymi się w projekcie i rozwiązuje konflikty, jeśli inne pluginy korzystają z tych samych bibliotek, modyfikując odpowiednio plik konfiguracyjny Gradle. Nie tylko czyni to sam projekt w Unity bardziej czytelnym – bo wszystkie biblioteki zostają przeniesione do pliku konfiguracyjnego Gradle, lecz również łatwiejszym w utrzymaniu, przy dodawaniu, usuwaniu lub aktualizowaniu innych pluginów.

Plik konfiguracyjny Gradle

Gradle do budowania projektów wykorzystuje plik konfiguracyjny build.gradle oraz język DSL (ang. Domain Specific Language). Jako, że Gradle jest domyślnym systemem budowania w Unity, to korzysta z domyślnego pliku konfiguracyjnego, niedostępnego z poziomu edytora Unity dla programisty. W przypadku, gdy w naszym projekcie wykorzystujemy zewnętrzne pluginy, musimy sami wygenerować taki plik w projekcie Unity, a następnie go odpowiednio zmodyfikować.

By wygenerować plik konfiguracyjny w Unity, na podstawie domyślnego, w oknie PlayerSettings należy zaznaczyć opcję Custom Gradle Template. Zaznaczenie tej opcji wygeneruje plik mainTemplate.gradle w katalogu Assets->Plugins->Android.

Unity and Gradle: mainTemplate.gradle
Zaznaczona opcja Custom Gradle Template w PlayerSettings->Publishing Settings.

Plik konfiguracyjny mainTemplate.gradle

Wygenerowany plik konfiguracyjny mainTemplate.gradle w całości wygląda nastepująco:

// GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN

buildscript {
    repositories {
        google()
        jcenter()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:3.2.0'
**BUILD_SCRIPT_DEPS**}
}

allprojects {
    repositories {
        google()
        jcenter()
        flatDir {
            dirs 'libs'
        }
    }
}

apply plugin: 'com.android.application'
**APPLY_PLUGINS**

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
**DEPS**}

android {
    compileSdkVersion **APIVERSION**
    buildToolsVersion '**BUILDTOOLS**'

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    defaultConfig {
        minSdkVersion **MINSDKVERSION**
        targetSdkVersion **TARGETSDKVERSION**
        applicationId '**APPLICATIONID**'
        ndk {
            abiFilters **ABIFILTERS**
        }
        versionCode **VERSIONCODE**
        versionName '**VERSIONNAME**'
    }

    lintOptions {
        abortOnError false
    }

    aaptOptions {
        noCompress = ['.unity3d', '.ress', '.resource', '.obb'**STREAMING_ASSETS**]
    }**SIGN**

    buildTypes {
        debug {
            minifyEnabled **MINIFY_DEBUG**
            useProguard **PROGUARD_DEBUG**
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-unity.txt'**USER_PROGUARD**
            jniDebuggable true
        }
        release {
            minifyEnabled **MINIFY_RELEASE**
            useProguard **PROGUARD_RELEASE**
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-unity.txt'**USER_PROGUARD****SIGNCONFIG**
        }
    }**PACKAGING_OPTIONS****SPLITS**
**BUILT_APK_LOCATION**
    bundle {
        language {
            enableSplit = false
        }
        density {
            enableSplit = false
        }
        abi {
            enableSplit = true
        }
    }
}**SPLITS_VERSION_CODE****REPOSITORIES****SOURCE_BUILD_SETUP**

Możemy go podzielić na takie składowe bloki:

  • komentarz Unity
  • buildscript
  • allprojects
  • plugins
  • dependencies
  • android

Unity w procesie budowania uzupełnia niektóre podane w pliku mainTemplate.gradle wartości, np. **TARGETSDKVERSION**; pełną listę takich zmiennych można zobaczyć TUTAJ.

Komentarz Unity

Domyślny komentarz Unity. Jeśli go usuniemy zapobiegniemy niechcianemu nadpisaniu pliku konfiguracyjnego.

// GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN

Blok buildscript

buildscript {
    repositories {
        google()
        jcenter()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:3.2.0'
**BUILD_SCRIPT_DEPS**}
}

Buildscript składa się z części repositories oraz dependencies. Dependencies określa nam zależności zawarte w pliku konfiguracyjnym, a repositories – z jakich repozytoriów zostaną one pobrane. Dotyczy to jednak tylko obszaru pliku konfiguracyjnego, a więc nie dotyczy zależności w projekcie, które zapisuje się w tym bloku.

W powyższym przypadku informujemy, że będziemy korzystać z Gradle Plugin w wersji 3.2 oraz z **BUILD_SCRIPT_DEPS** uzupełnianych przez silnik Unity.

Blok allprojects

allprojects {
    repositories {
        google()
        jcenter()
        flatDir {
            dirs 'libs'
        }
    }
}

Gdy nasza aplikacja posiada wiele pluginów zewnętrznych może się zdarzyć, że w naszym projekcie znajdą się inne pliki konfiguracyjne *.gradle. W takiej sytuacji repozytoria oraz zależności definiuje blok allprojects. Wyżej zdefiniowano tylko ścieżki do repozytoriów: google(), jcenter() oraz do flatDir. FlatDir to nasze lokalne repozytorium, czyli wszystkie biblioteki, które są zawarte lokalnie na urządzeniu.

Czasem w mainTemplate.gradle są dwa takie bloki. Jeden stworzony domyślnie przez Unity, pokazany wyżej, a drugi stworzony, np. przez PlayServicesResolvera, z dodatkowymi ścieżkami do repozytoriów mavena lub lokalnych folderów. Poniżej przykład bloku allprojects dodanego przez PlayServicesResolver.

// Android Resolver Repos Start
allprojects {
    repositories {
        maven {
            url "https://maven.google.com"
        }
        maven {
            url "file:////TWÓJPROJEKT/Assets/GooglePlayGames/Editor/m2repository" 
//Assets/GooglePlayGames/Editor/GooglePlayGamesPluginDependencies.xml:11
        }
        mavenLocal()
        jcenter()
        mavenCentral()
    }
}
// Android Resolver Repos End

Blok plugins

apply plugin: 'com.android.application'
**APPLY_PLUGINS**

Pierwsza linijka oznacza, że nasza aplikacja będzie przeznaczona na system Android. Kolejna to pluginy dodawane przez Unity. Nie zdarzyło mi się jednak, bym miała potrzebę modyfikowania lub dodawania innych pluginów w tym bloku.

Blok dependencies

Teraz dochodzimy do ostatniego bloku, który omówimy w tym wpisie: bloku zależności w naszym projekcie. Modyfikujemy go najczęściej nie tylko sami, lecz również przez zewnętrzne pluginy, np. PlayServicesResolvera.

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
**DEPS**}

Z blokiem dependencies spotkaliśmy się już wyżej, w bloku buildscript, w którym określa się zależności dotyczące Gradle. Tym razem jednak podaje się zależności dotyczące naszego projektu. W domyślnym mainTemplate, w drugiej linijce, widzimy, że dodajemy wszystkie biblioteki, które znajdują się w naszym projekcie, włącznie z plikami *.jar (ang. Java archive). Jednak jeśli korzystamy z GoogleServiceResolvera i np. SDK reklamowych, możemy się spotkać z takim wyglądem tego bloku:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:multidex:1.0.3'
// Android Resolver Dependencies Start
    compile 'com.android.support:support-v4:28.0.0' 
// Assets/MoPub/Scripts/Editor/MoPubDependencies.xml:3
    compile 'com.applovin:applovin-sdk:9.7.1' 
// Assets/MoPub/Mediation/AppLovin/Editor/AppLovinDependencies.xml:4
    compile 'com.facebook.android:audience-network-sdk:5.3.1' 
// Assets/MoPub/Mediation/FacebookAudienceNetwork/Editor/FacebookAudienceNetworkDependencies.xml:4
    compile 'com.google.android.gms:play-services-ads:17.2.1' 
// Assets/MoPub/Mediation/AdMob/Editor/AdMobDependencies.xml:4
    compile 'com.google.games:gpgs-plugin-support:0.9.64'
// Android Resolver Dependencies End
**DEPS**}

Zaważyć można dodatkowe biblioteki. Pierwsza, dotycząca multidex’a w wersji 1.0.3 została dopisana ręcznie. Wynika to z tego, że Dalvik Executable (DEX) przyjmuje tylko do 65,536 metod w jednym pliku wykonywalnym. Jeśli nasz projekt, razem z bibliotekami, zawiera ich więcej, trzeba skonfigurować projekt tak, by radził sobie z kilkoma plikami DEX, za co odpowiada m.in ta linijka.

Kolejne zależności wynikają z wykorzystania zewnętrznego SDK reklamowego MoPub’a. Dołącza się więc kolejne biblioteki: support-v4, Applovin oraz Facebook Audience Network, by mediacje z tych sieci reklamowych działały, android.gms:play-services-ads oraz games:gpgs-plugin-support z Google Play Games. PlayServicesResolver na podstawie danych z pluginu MoPub uzupełnił plik konfiguracyjny mainTemplate o te zależności.

Każdy projekt będzie miał inne zawartości tego bloku, jednak wspólne jest jego częste modyfikowanie wraz z rozrostem projektu. Jesli dodajemy lub usuwamy zewnętrzne pluginy, na pewno zauważymy zmiany w tym bloku.

To właśnie stąd bierze się większość problemów z budowaniem projektu z Gradle, a wynikają one z:

  • bibliotek, które się ze sobą pokrywają
  • braku bibliotek potrzebnych do działania naszej aplikacji

Więcej o samym bloku android przeczytaj tutaj, w kolejnym wpisie o pliku mainTemplate. 🙂

Zapisz się do newslettera, odbieraj darmowe materiały do nauki i bądź na bieżąco z nowymi artykułami!

Invalid email address
Zgadzam się na wysyłkę newslettera.
Polityka prywatności