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");
}
}