当前位置:网站首页>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 .
边栏推荐
- 【数字IC验证快速入门】26、SystemVerilog项目实践之AHB-SRAMC(6)(APB协议基本要点)
- [make a boat diary] [shapr3d STL format to gcode]
- 一大波开源小抄来袭
- Window环境下配置Mongodb数据库
- Vertex shader to slice shader procedure, varying variable
- Do you know the relationship between the most important indicators of two strong wind control and the quality of the customer base
- Mathematical modeling -- what is mathematical modeling
- 使用cpolar建立一个商业网站(2)
- Annexb and avcc are two methods of data segmentation in decoding
- How to create Apple Developer personal account P8 certificate
猜你喜欢
Super simple and fully automated generation super signature system (cloud Xiaoduo minclouds.com cloud service instance), free application in-house test app distribution and hosting platform, maintenan
How to create Apple Developer personal account P8 certificate
【OBS】RTMPSockBuf_ Fill, remote host closed connection.
Unity's ASE realizes cartoon flame
[deep learning] image hyperspectral experiment: srcnn/fsrcnn
Async and await
Cut ffmpeg as needed, and use emscripten to compile and run
2. 堆排序『较难理解的排序』
LeetCode1_ Sum of two numbers
Steps to create P8 certificate and warehousing account
随机推荐
Mathematical modeling -- what is mathematical modeling
知否|两大风控最重要指标与客群好坏的关系分析
Nacos一致性协议 CP/AP/JRaft/Distro协议
LeetCode1_ Sum of two numbers
2022 all open source enterprise card issuing network repair short website and other bugs_ 2022 enterprise level multi merchant card issuing platform source code
#HPDC智能基座人才发展峰会随笔
MongoDB数据库基础知识整理
Steps to create P8 certificate and warehousing account
The difference between full-time graduate students and part-time graduate students!
Points for attention in porting gd32 F4 series programs to gd32 F3 series
webgl_ Enter the three-dimensional world (2)
Super simple and fully automated generation super signature system (cloud Xiaoduo minclouds.com cloud service instance), free application in-house test app distribution and hosting platform, maintenan
连接ftp服务器教程
从 1.5 开始搭建一个微服务框架链路追踪 traceId
一大波开源小抄来袭
Annexb and avcc are two methods of data segmentation in decoding
Unity's ASE achieves full screen sand blowing effect
【数字IC验证快速入门】25、SystemVerilog项目实践之AHB-SRAMC(5)(AHB 重点回顾,要点提炼)
LeetCode2_ Add two numbers
【搞船日记】【Shapr3D的STL格式转Gcode】