Verwendung von Asset-Bundles in Unity
Unity verfügt über viele nützliche Funktionen, eine davon ist die Unterstützung von Asset Bundles.
Was sind Vermögenspakete?
Asset-Bundles sind Dateien, die Spiel-Assets enthalten, von einfachen Assets wie 3D-Modellen, Texturen und Audioclips bis hin zu komplexeren Assets wie Szenen und Prefabs.
Skripte können jedoch nicht in Asset-Bundles eingebunden werden, sondern nur deren Referenzen. Seien Sie daher beim Umbenennen oder Verschieben vorsichtig, da dadurch die Verbindung unterbrochen wird und Sie die Asset-Bundles neu erstellen müssen, damit sie wieder funktionieren.
Wann sollten Asset-Bundles verwendet werden?
Verwenden Sie Asset-Bundles, wenn Ihr Spiel über viele Assets verfügt und deren Einbeziehung in den Build sich auf die anfängliche Downloadzeit auswirkt.
Asset-Bundles exportieren
Der Export von Asset-Bundles erfolgt in zwei Schritten: Asset-Bundle-Namen zuweisen und mit dem Editor script erstellen.
Asset-Bundle-Namen zuweisen
Um den Asset-Bundle-Namen zuzuweisen, wählen Sie das Asset in der Projektansicht aus (dies kann Prefab, Texture oder sogar eine Szene sein), klicken Sie dann in der Inspektoransicht ganz unten auf das Dropdown-Menü und dann auf 'New...' (bzw Klicken Sie auf den Namen des vorhandenen Asset-Bundles).
Wenn Sie mehreren Assets denselben Bundle-Namen zuweisen, werden diese im selben Asset-Bundle zusammengefasst. Es wird empfohlen, Szenen getrennt vom Rest der Assets zu packen.
Außerdem müssen Sie nicht jedem Asset einen Asset-Bundle-Namen zuweisen. Normalerweise müssen Sie nur den Bundle-Namen dem Hauptfertigteil oder -Asset zuweisen, die restlichen Abhängigkeiten werden automatisch einbezogen.
Aufbau von Asset-Bundles
Um Asset-Bundles zu erstellen, führen Sie die folgenden Schritte aus:
- Erstellen Sie einen neuen Ordner mit dem Namen Editor (falls Sie noch keinen haben)
- Erstellen ein neues Skript im Editor-Ordner, nennen Sie es „BuildAssetBundles“ und fügen Sie dann den folgenden Code ein:
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);
}
}
Nach dem Speichern werden Sie feststellen, dass eine Menüschaltfläche hinzugefügt wird (Build -> AssetBundles erstellen). Wenn Sie darauf klicken, werden die Asset-Bundles erstellt und im Ordner "__Bundles" abgelegt.
Laden von Asset-Bundles
Um das Asset Bundle zu laden, muss es zunächst mit UnityWebRequest heruntergeladen und dann mit einer speziellen Funktion entpackt werden. Im Allgemeinen gibt es zwei Arten von Asset-Bundles: solche, die Assets enthalten, und solche, die Szenen enthalten.
Laden von Assets aus den Asset-Bundles
Der folgende Code lädt das Asset-Bundle mit dem Namen "fpsplayer" herunter, extrahiert dann das Prefab mit dem Namen "FPSPlayer" und instanziiert es in der Szene:
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);
}
}
Laden von Szenen aus den Asset-Bundles
Das Laden der Szene aus dem Asset Bundle erfolgt etwas anders.
Der folgende Code lädt das Asset-Bundle mit einer Szene herunter und stellt es zum Laden bereit:
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");
}
}