当前位置:网站首页>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 .
边栏推荐
- Wechat applet 01
- Cut ffmpeg as needed, and use emscripten to compile and run
- 【兰州大学】考研初试复试资料分享
- 【OBS】RTMPSockBuf_ Fill, remote host closed connection.
- 使用cpolar建立一个商业网站(2)
- 【數字IC驗證快速入門】20、SystemVerilog學習之基本語法7(覆蓋率驅動...內含實踐練習)
- 居然从408改考自命题!211华北电力大学(北京)
- 【数据挖掘】视觉模式挖掘:Hog特征+余弦相似度/k-means聚类
- [markdown grammar advanced] make your blog more exciting (IV: set font style and color comparison table)
- How to understand that binary complement represents negative numbers
猜你喜欢
MySQL bit type resolution
[understanding of opportunity -40]: direction, rules, choice, effort, fairness, cognition, ability, action, read the five layers of perception of 3GPP 6G white paper
Gd32 F3 pin mapping problem SW interface cannot be burned
OpenGL's distinction and understanding of VAO, VBO and EBO
The rebound problem of using Scrollview in cocos Creator
What is data leakage
Qu'est - ce qu'une violation de données
What is Base64?
LeetCode1_ Sum of two numbers
Super signature principle (fully automated super signature) [Yun Xiaoduo]
随机推荐
[quick start of Digital IC Verification] 18. Basic grammar of SystemVerilog learning 5 (concurrent threads... Including practical exercises)
[follow Jiangke University STM32] stm32f103c8t6_ PWM controlled DC motor_ code
#HPDC智能基座人才发展峰会随笔
2. Basic knowledge of golang
How to deploy the super signature distribution platform system?
Share the technical details of super signature system construction
Annexb and avcc are two methods of data segmentation in decoding
Nacos conformance protocol cp/ap/jraft/distro protocol
Use of SVN
Unity之ASE实现卡通火焰
Using eating in cocos Creator
【数字IC验证快速入门】22、SystemVerilog项目实践之AHB-SRAMC(2)(AMBA总线介绍)
[deep learning] image hyperspectral experiment: srcnn/fsrcnn
./ Functions of configure, make and make install
Points for attention in porting gd32 F4 series programs to gd32 F3 series
如何在opensea批量发布NFT(Rinkeby测试网)
[server data recovery] data recovery case of raid failure of a Dell server
Runnable是否可以中断
Getting started with webgl (2)
Gd32 F3 pin mapping problem SW interface cannot be burned