当前位置:网站首页>AB package details in unity (super detail, features, packaging, loading, manager)
AB package details in unity (super detail, features, packaging, loading, manager)
2022-07-07 15:44:00 【Listen to the rain outside the window】
Unity Medium AssetBundle Detailed explanation
AssetBundle The concept of
AssetBundle also called AB package , yes Unity Provides a resource compression package for storing resources .
Unity Medium AssetBundle The system is an extension of resource management , By distributing resources in different AB The package can minimize the memory pressure at run time , You can dynamically load and unload AB package , Then selectively load the content .
AssetBundle The advantages of
AB Package storage location customization , Then it can be put into a readable and writable path to facilitate hot update
AB Package custom compression , You can choose not to compress or choose LZMA and LZ4 Equal compression mode , Reduce the size of the bag , Faster network transmission .
Resources can be distributed in different AB In bag , Minimize memory pressure at runtime , It can be used and loaded immediately , Selectively load the required content .
AB The package supports dynamic updates in the later stage , Significantly reduce the size of the initial installation package , Non core resources AB Upload the package to the server , Late runtime dynamic loading , Improve user experience .
AssetBundle and Resources Comparison
AssetBundle | Resources | ||
---|---|---|---|
Resources can be distributed in multiple packages | All resources are packaged into a big package | ||
Flexible customization of storage location | It must be stored in Resources Under the table of contents | ||
Flexible compression (LZMA,LZ4) | All resources will be compressed into binary | ||
Support dynamic update in later period | After packaging, the resource is read-only and cannot be changed dynamically | ||
AssetBundle Characteristics of
AB Packages can store most Unity Resources but cannot be stored directly C# Script , So the hot update of code needs to use Lua Or store the compiled DLL file .
AB Packages cannot be loaded repeatedly , When AB After the package has been loaded into memory, it must be unloaded before it can be reloaded .
Multiple resources are distributed in different AB The package may have some resources such as the mapping of a prefab that are not under the same package , Direct loading will cause some resources to be lost , namely AB There are dependencies between packages , Loading the current AB Packages need to be loaded together with the packages they depend on .
After packing , A main package will be automatically generated ( The name of the main package varies with the platform ), The main package is manifest The version number will be stored under 、 Check code (CRC)、 Information about all other packages ( name 、 Dependency relationship )
AssetBundle Full packaging process
This is mainly about Unity Official AB Package management plug-in AssetBundle Browser package
1、AssetBundleBrowser Access to plug-ins
Unity 2019 The version can be directly in Windows —> PackageManager Find this plug-in inside and install it directly
2020 After version or other versions may be 1 The plug-in cannot be found in the method , You can go to github Search and download compressed packages , Download address https://github.com/Unity-Technologies/AssetBundles-Browser
Unzip the downloaded installation package to Unity engineering Packages Under the folder ( Be sure to decompress )
2、AssetBundleBrowser Use of panels
After getting and installing the plug-in correctly , adopt Windows ----> AssetBundle Browser Open down AB Package management panel There are three panels
Configure panel : Can view the current AB Basic information about the package and its internal resources ( size , resources , Dependence, etc )
Build panel : be responsible for AssetBundle Packaging related settings Press Build You can pack it
Three compression methods
- NoCompression: Uncompressed , Fast decompression , Big bag , Not recommended .
- LZMA: Minimum compression , Slow decompression , Use one resource to decompress all resources in the package .
- LZ4: Slightly larger compression , Fast decompression , Decompress whatever you use , Low memory usage , It is more recommended to use .
Generally, the settings that need to be changed are the relevant option settings checked in the figure .
Inspect panel : It is mainly used to view the packaged AB Some details of the package file ( size , Resource path, etc )
3、 Set the AssetBundle package
In the case of resources that need to be packaged Inspector Under the panel, you can choose where it should be placed AB It's a bag , Can also pass New newly build AB Package puts resources into , Put it in again Build Packaging can put this resource into the corresponding AB In bag .
AssetBundle Manager
utilize AssetBundleBrowser Can be easily implemented AB Package work , More importantly, how to AB Load the resources in the package and use them ,Unity A set of API Can achieve AB Package loading and resource loading .
AB The main requirements of package manager : Load specified AB The specified resources under the package , The basic steps are as follows :
- Load the resource AB Package and all its dependent packages ( According to the main package manifest Information find dependent package name )
- from AB Load the specified resource in the package ( By name , type )
- Unload the loaded when it is no longer in use AB package
Mainly related API
//AB Package loading required related API
//1. Load according to the path AB package Be careful AB Packages cannot be loaded repeatedly
AssetBundle ab = AssetBundle.LoadFromFile(path);
//2. load ab Resources with specified names and types under the package
T obj = ab.LoadAsset<T>(ResourceName); // Generic loading
Object obj = ab.LoadAsset(ResourceName); // Non generic loading The type of forced rotation is required for subsequent use
Object obj = ab.LoadAsset(ResourceName,Type); // The parameter indicates the resource type Prevent duplicate names
T obj = ab.LoadAssetAsync<T>(resName); // Asynchronous generic loading
Object obj = ab.LoadAssetAsync(resName); // Asynchronous non generic loading
Object obj = ab.LoadAssetAsync(resName,Type); // The parameter indicates the resource type Prevent duplicate names
//3. uninstall ab package bool The parameter represents whether the deletion has been made from AB Resources loaded into the scene in the package ( It's usually false)
ab.UnLoad(false); // Uninstall a single ab package
AssetBundle.UnloadAllAssetBundles(false); // Uninstall all AB package
Here is AB Detailed code and comments of package manager , The content of the singleton mode involved in it will be briefly introduced later .
ABManager.cs
using System;
using System.Net.Mime;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Common
{
/// <summary>
/// AB Package manager Globally unique Use singleton mode
/// </summary>
public class ABManager : MonoSingleton<ABManager>
{
//AB Package cache --- solve AB The package cannot be loaded repeatedly It is also conducive to improving efficiency .
private Dictionary<string, AssetBundle> abCache;
private AssetBundle mainAB = null; // Main package
private AssetBundleManifest mainManifest = null; // Configuration files in the main package --- To obtain dependent packages
// The basic path under each platform --- Use macros to judge streamingAssets route
private string basePath {
get
{
// Use StreamingAssets Path note AB When packing Check copy to streamingAssets
#if UNITY_EDITOR || UNITY_STANDALONE
return Application.dataPath + "/StreamingAssets/";
#elif UNITY_IPHONE
return Application.dataPath + "/Raw/";
#elif UNITY_ANDROID
return Application.dataPath + "!/assets/";
#endif
}
}
// The name of the main package under each platform --- It is used to load the main package to obtain dependency information
private string mainABName
{
get
{
#if UNITY_EDITOR || UNITY_STANDALONE
return "StandaloneWindows";
#elif UNITY_IPHONE
return "IOS";
#elif UNITY_ANDROID
return "Android";
#endif
}
}
// It inherits the initialization function provided by the singleton mode
protected override void Init()
{
base.Init();
// Initialize Dictionary
abCache = new Dictionary<string, AssetBundle>();
}
// load AB package
private AssetBundle LoadABPackage(string abName)
{
AssetBundle ab;
// load ab package , You need to load its dependent packages .
if (mainAB == null)
{
// Load the main package according to the basic path and main package name under each platform
mainAB = AssetBundle.LoadFromFile(basePath + mainABName);
// Get the AssetBundleManifest Resource file ( There is dependent information )
mainManifest = mainAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
}
// according to manifest Get the names of all dependent packages Fix API
string[] dependencies = mainManifest.GetAllDependencies(abName);
// Cycle through all dependent packages
for (int i = 0; i < dependencies.Length; i++)
{
// If it is not in the cache, add
if (!abCache.ContainsKey(dependencies[i]))
{
// Load according to the dependent package name
ab = AssetBundle.LoadFromFile(basePath + dependencies[i]);
// Pay attention to adding to the cache Prevent duplicate loading AB package
abCache.Add(dependencies[i], ab);
}
}
// Load the target package -- Similarly, pay attention to the cache problem
if (abCache.ContainsKey(abName)) return abCache[abName];
else
{
ab = AssetBundle.LoadFromFile(basePath + abName);
abCache.Add(abName, ab);
return ab;
}
}
//================== Three resource synchronous loading methods ==================
// Provide a variety of calling methods It is convenient for other languages to call (Lua Bad support for generics )
#region Three overloads loaded synchronously
/// <summary>
/// Load resources synchronously --- Generic loading Simple and intuitive No need to show the conversion
/// </summary>
/// <param name="abName">ab The name of the package </param>
/// <param name="resName"> Resource name </param>
public T LoadResource<T>(string abName,string resName)where T:Object
{
// Load the target package
AssetBundle ab = LoadABPackage(abName);
// Returns the resource
return ab.LoadAsset<T>(resName);
}
// Do not specify type It is not recommended to use when there are duplicate names The conversion type should be displayed when using
public Object LoadResource(string abName,string resName)
{
// Load the target package
AssetBundle ab = LoadABPackage(abName);
// Returns the resource
return ab.LoadAsset(resName);
}
// Use parameters to pass types , Suitable for language calls that are not supported by generics , Forced rotation type is required when using
public Object LoadResource(string abName, string resName,System.Type type)
{
// Load the target package
AssetBundle ab = LoadABPackage(abName);
// Returns the resource
return ab.LoadAsset(resName,type);
}
#endregion
//================ There are three ways to load resources asynchronously ======================
/// <summary>
/// Provide asynchronous loading ---- Be careful This loading AB Packages are loaded synchronously , Just loading resources is asynchronous
/// </summary>
/// <param name="abName">ab Package name </param>
/// <param name="resName"> Resource name </param>
public void LoadResourceAsync(string abName,string resName, System.Action<Object> finishLoadObjectHandler)
{
AssetBundle ab = LoadABPackage(abName);
// Start the process Provide the delegation after the resource is loaded successfully
StartCoroutine(LoadRes(ab,resName,finishLoadObjectHandler));
}
private IEnumerator LoadRes(AssetBundle ab,string resName, System.Action<Object> finishLoadObjectHandler)
{
if (ab == null) yield break;
// Load resources asynchronously API
AssetBundleRequest abr = ab.LoadAssetAsync(resName);
yield return abr;
// Delegate call processing logic
finishLoadObjectHandler(abr.asset);
}
// according to Type Load resources asynchronously
public void LoadResourceAsync(string abName, string resName,System.Type type, System.Action<Object> finishLoadObjectHandler)
{
AssetBundle ab = LoadABPackage(abName);
StartCoroutine(LoadRes(ab, resName,type, finishLoadObjectHandler));
}
private IEnumerator LoadRes(AssetBundle ab, string resName,System.Type type, System.Action<Object> finishLoadObjectHandler)
{
if (ab == null) yield break;
AssetBundleRequest abr = ab.LoadAssetAsync(resName,type);
yield return abr;
// Delegate call processing logic
finishLoadObjectHandler(abr.asset);
}
// Generic loading
public void LoadResourceAsync<T>(string abName, string resName, System.Action<Object> finishLoadObjectHandler)where T:Object
{
AssetBundle ab = LoadABPackage(abName);
StartCoroutine(LoadRes<T>(ab, resName, finishLoadObjectHandler));
}
private IEnumerator LoadRes<T>(AssetBundle ab, string resName, System.Action<Object> finishLoadObjectHandler)where T:Object
{
if (ab == null) yield break;
AssetBundleRequest abr = ab.LoadAssetAsync<T>(resName);
yield return abr;
// Delegate call processing logic
finishLoadObjectHandler(abr.asset as T);
}
//====================AB There are two ways to uninstall packages =================
// Single package uninstall
public void UnLoad(string abName)
{
if(abCache.ContainsKey(abName))
{
abCache[abName].Unload(false);
// Note that the cache should be removed together
abCache.Remove(abName);
}
}
// Uninstall all packages
public void UnLoadAll()
{
AssetBundle.UnloadAllAssetBundles(false);
// Pay attention to emptying the cache
abCache.Clear();
mainAB = null;
mainManifest = null;
}
}
}
The script singleton class inherited by the above manager is as follows
MonoSingleton.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Common
{
///<summary>
/// Script singleton class , Responsible for creating instances for unique scripts
///<summary>
public class MonoSingleton<T> : MonoBehaviour where T:MonoSingleton<T> // Note that this constraint is T Must be itself or a subclass
{
/* Instead of creating an instance directly in a script that needs to be uniquely created ,Awake Problems to be solved in the initialization process 1. Duplicate code 2. stay Awake Initialization inside , Other scripts are in Awake It may be called in Null Abnormal conditions of */
// solve 1: Creating instances using generics solve 2: Use load on demand ( That is, when there are other script calls get Load in )
private static T instance; // Create private object record value , You can assign values only once to avoid multiple assignments
public static T Instance
{
// Implement on-demand loading
get
{
// When it has been assigned , You can go back directly
if (instance != null) return instance;
instance = FindObjectOfType<T>();
// To prevent the script from hanging on the object , Exception not found , You can create an empty object and hang it
if (instance == null)
{
// If you create an object , The script on it will be called when it is created Awake That is to call T Of Awake(T Of Awake Is actually the name of the inherited parent class )
// So there is no need to instance assignment , It will be in Awake Assignment in , It will initialize naturally, so there is no need to init()
/*instance = */
new GameObject("Singleton of "+typeof(T)).AddComponent<T>();
}
else instance.Init(); // Guarantee Init Only once
return instance;
}
}
private void Awake()
{
// If there are no other scripts Awake Call this instance , Then you can Awake Self initialization in instance
instance = this as T;
// initialization
Init();
}
// Subclasses initialize members if placed in Awake There will still be Null So make one by yourself init Function solution ( It's not necessary to use it )
protected virtual void Init()
{
}
}
}
In addition to the script singleton class above There are two other singleton patterns that do not need inheritance MonoBehaviour Pure C# The singleton pattern Interested readers can learn about Hungry and lazy mode in singleton mode .
边栏推荐
- Streaming end, server end, player end
- webgl_ Enter the three-dimensional world (2)
- Webcodecs parameter settings -avc1.42e01e meaning
- MySQL bit类型解析
- 【数字IC验证快速入门】22、SystemVerilog项目实践之AHB-SRAMC(2)(AMBA总线介绍)
- 【数字IC验证快速入门】19、SystemVerilog学习之基本语法6(线程内部通信...内含实践练习)
- 【數字IC驗證快速入門】20、SystemVerilog學習之基本語法7(覆蓋率驅動...內含實踐練習)
- Oracle控制文件丢失恢复归档模式方法
- 【数字IC验证快速入门】23、SystemVerilog项目实践之AHB-SRAMC(3)(AHB协议基本要点)
- leetcode 241. Different ways to add parentheses design priority for operational expressions (medium)
猜你喜欢
[quick start of Digital IC Verification] 22. Ahb-sramc of SystemVerilog project practice (2) (Introduction to AMBA bus)
What is data leakage
Create lib Library in keil and use lib Library
Window环境下配置Mongodb数据库
[quick start of Digital IC Verification] 24. AHB sramc of SystemVerilog project practice (4) (AHB continues to deepen)
Configure mongodb database in window environment
【数字IC验证快速入门】24、SystemVerilog项目实践之AHB-SRAMC(4)(AHB继续深入)
Unity之ASE实现全屏风沙效果
Tkinter after how to refresh data and cancel refreshing
2. Heap sort "hard to understand sort"
随机推荐
HW primary flow monitoring, what should we do
【搞船日记】【Shapr3D的STL格式转Gcode】
Getting started with webgl (3)
Typescript release 4.8 beta
2. Basic knowledge of golang
Webcodecs parameter settings -avc1.42e01e meaning
The download button and debug button in keil are grayed out
Basic knowledge sorting of mongodb database
webgl_ Graphic transformation (rotation, translation, zoom)
Shader Language
银行需要搭建智能客服模块的中台能力,驱动全场景智能客服务升级
【數據挖掘】視覺模式挖掘:Hog特征+餘弦相似度/k-means聚類
LeetCode2_ Add two numbers
【數字IC驗證快速入門】20、SystemVerilog學習之基本語法7(覆蓋率驅動...內含實踐練習)
Unity之ASE实现卡通火焰
最安全的证券交易app都有哪些
MongoDB数据库基础知识整理
Getting started with webgl (4)
【数字IC验证快速入门】19、SystemVerilog学习之基本语法6(线程内部通信...内含实践练习)
Whether runnable can be interrupted