Asset Bundle-brug i Unity

Unity har mange nyttige funktioner, en af ​​dem er understøttelse af Asset Bundles.

Hvad er Asset Bundles?

Asset Bundles er filer, der indeholder spilaktiver, fra simple aktiver såsom 3D-modeller, teksturer og lydklip til mere komplekse, såsom Scener og Prefabs.

Scripts kan dog ikke inkluderes i Asset Bundles, kun deres referencer, så vær forsigtig, når du omdøber eller flytter dem, da det vil bryde forbindelsen, og du bliver nødt til at genopbygge Asset Bundles for at få dem til at fungere igen.

Hvornår skal man bruge Asset Bundles?

Brug Asset Bundles, når dit spil har mange aktiver, og at inkludere dem i buildet påvirker den indledende downloadtid.

Eksport af aktivpakker

Eksport af Asset Bundles foregår i to trin: tildeling af Asset Bundle-navne og opbygning af dem ved hjælp af Editoren script.

Tildeling af aktivbundtnavne

For at tildele aktivpakkens navn skal du vælge aktivet i projektvisningen (dette kan være præfabrikeret, tekstur eller endda en scene), og derefter i Inspektør-visningen helt nederst, klik på rullemenuen, og klik derefter på 'New...' (eller klik på det eksisterende aktivpakkenavn).

Hvis du tildeler det samme bundtnavn til flere aktiver, pakkes dem sammen i den samme aktivpakke. Det tilrådes at pakke Scener adskilt fra resten af ​​aktiverne.

Du behøver heller ikke at tildele et aktivbundtnavn til hvert aktiv. Typisk behøver du kun at tildele bundtnavnet til det primære præfabrikat eller aktiv, resten af ​​afhængighederne vil automatisk blive inkluderet.

Opbygning af aktivpakker

Følg nedenstående trin for at bygge aktivpakker:

  • Opret en ny mappe kaldet Editor (hvis du ikke har nogen)
  • Opret et nyt script inde i Editor-mappen, navngiv det BuildAssetBundles og indsæt derefter koden nedenfor i det:

BuildAssetBundles.cs

using UnityEngine;
using UnityEditor;

public class BuildAssetBundles
{
    [MenuItem("Build/Build AssetBundles")]
    static void BuildAllAssetBundles()
    {
        string outputFolder = "Assets/__Bundles";

        //Check if __Bundles folder exist
        if (!AssetDatabase.IsValidFolder(outputFolder))
        {
            Debug.Log("Folder '__Bundles' does not exist, creating new folder");

            AssetDatabase.CreateFolder("Assets", "__Bundles");
        }

        BuildPipeline.BuildAssetBundles(outputFolder, BuildAssetBundleOptions.ChunkBasedCompression, EditorUserBuildSettings.activeBuildTarget);
    }
}

Når du har gemt det, vil du bemærke, at det vil tilføje en menuknap (Byg -> Byg AssetBundles). Hvis du klikker på den, opbygges Asset Bundles og placeres i mappen "__Bundles".

Indlæser aktivpakker

For at indlæse Asset Bundle skal det først downloades ved hjælp af UnityWebRequest og derefter pakkes ud ved hjælp af en speciel funktion. Generelt er der 2 typer aktivbundter, dem der indeholder aktiver og dem der indeholder scener.

Indlæsning af aktiver fra aktivpakkerne

Koden nedenfor downloader Asset Bundle med navnet "fpsplayer" og udtrækker derefter præfabrikatet med navnet "FPSPlayer" og instansierer det i scenen:

        int assetBundleVersion = 1; // Changing this number will force Asset Bundle reload
        string assetBundlePath = "file://" + Application.dataPath + "/__Bundles/" + "fpsplayer"; // Path to Asset Bundle file
        using (UnityEngine.Networking.UnityWebRequest www = UnityEngine.Networking.UnityWebRequestAssetBundle.GetAssetBundle(assetBundlePath, (uint)assetBundleVersion, 0))
        {
            yield return www.SendWebRequest();

            if (www.isNetworkError || www.isHttpError)
            {
                Debug.LogError("AssetBundle Error: " + www.error);
                yield return null;
            }
            else
            {
                // Get downloaded Asset Bundle
                AssetBundle assetBundle = UnityEngine.Networking.DownloadHandlerAssetBundle.GetContent(www);
                // Extract Prefab named "FPSPlayer" from the Asset Bundle
                GameObject playerPrefab = assetBundle.LoadAsset("FPSPlayer") as GameObject;
                // Instantiate Player Prefab
                Instantiate(playerPrefab, Vector3.zero, Quaternion.identity);
                // Unload Asset Bundle from memory (but do not destroy the existing instance(s))
                assetBundle.Unload(false);
            }
        }

Indlæser scener fra aktivpakkerne

Indlæsning af scene fra Asset Bundle udføres lidt anderledes.

Koden nedenfor vil downloade aktivpakken med en scene og gøre den tilgængelig til indlæsning:

        int assetBundleVersion = 1; // Changing this number will force Asset Bundle reload
        string assetBundlePath = "file://" + Application.dataPath + "/__Bundles/" + "testscene"; // Path to Asset Bundle file
        using (UnityEngine.Networking.UnityWebRequest www = UnityEngine.Networking.UnityWebRequestAssetBundle.GetAssetBundle(assetBundlePath, (uint)assetBundleVersion, 0))
        {
            yield return www.SendWebRequest();

            if (www.isNetworkError || www.isHttpError)
            {
                Debug.LogError("AssetBundle Error: " + www.error);
                yield return null;
            }
            else
            {
                // Get downloaded Asset Bundle (This will make the Scene available for load)
                AssetBundle assetBundle = UnityEngine.Networking.DownloadHandlerAssetBundle.GetContent(www);
                // Load the Scene extracted from the Asset Bundle
                UnityEngine.SceneManagement.SceneManager.LoadScene("TestScene");
            }
        }