当前位置:网站首页>Unity3d:assetbundle simulation loading, synchronous loading, asynchronous loading, dependent package loading, automatic labeling, AB browser, incremental packaging

Unity3d:assetbundle simulation loading, synchronous loading, asynchronous loading, dependent package loading, automatic labeling, AB browser, incremental packaging

2022-07-23 12:53:00 Sixi Liyu

AB Automatically set labels

Every... In the folder prefab, Pack them individually into one assetbundle, Used in model , Single UI panel
 Insert picture description here

Each folder in the folder is packaged into one assetbundle, Applicable to atlas
 Insert picture description here

all AB The distributor configuration data is Editor/AssetBundle/Database/AssetPackage in , There is a mapping structure of the directory under this directory , Each serialized file corresponds to one AB The dispenser
 Insert picture description here

Execute before packaging make tag, Read the corresponding configuration above , Automatic setting ab Label and name

        public AssetBundleChecker(AssetBundleCheckerConfig config)
        {
    
            this.config = config;
            assetsPath = AssetBundleUtility.PackagePathToAssetsPath(config.PackagePath);
            importer = AssetBundleImporter.GetAtPath(assetsPath);
        }

        public void CheckAssetBundleName()
        {
    
            if (!importer.IsValid)
            {
    
                return;
            }

            var checkerFilters = config.CheckerFilters;
            if (checkerFilters == null || checkerFilters.Count == 0)
            {
    
                importer.assetBundleName = assetsPath;
                string[] bufName = importer.assetBundleName.Split('.');
                MenuAssetBundle.m_abNameStr.AppendFormat("public const string {0} = \"{1}\";", bufName[0], bufName[0]);
                MenuAssetBundle.m_abNameStr.AppendLine();
            }

AB pack

Adopt incremental packaging , Only the changed resources will be packaged
BuildPipeline.BuildAssetBundles(info.outputDirectory, info.options, info.buildTarget);
Call this function ,unity It will be automatically packaged according to the label of the resource , And it is incremental packaging ,

  1. There is no change to the resource bundle package , Repackaging will not be triggered ;
  2. Resources have not changed , Even if bundle The package was deleted ,unity Nor will it be repackaged ;
  3. Generate bundle The package corresponds to manifase Have been deleted , It's going to be repackaged ;
  4. have access to BuildAssetBundleOptions.ForceRebuildAssetBundle Parameter triggers forced repackaging .

After packing md5 iw

FileStream fs = new FileStream(newFilePath, FileMode.CreateNew);
            StreamWriter sw = new StreamWriter(fs);
            for (int i = 0; i < files.Count; i++)
            {
    
                string file = files[i];
                //if (file.Contains("StreamingAssets")) continue;
                string ext = Path.GetExtension(file);
                if (file.EndsWith(".meta") || file.Contains(".DS_Store")) continue;

                string md5 = NTG.Util.md5file(file);
                string value = file.Replace(m_OutputPath + "/", string.Empty);

                FileInfo fileInfo = new FileInfo(file);
                int size = (int)(fileInfo.Length / 1024) + 1;

                //if (value != "StreamingAssets" && value != "StreamingAssets.manifest")
                sw.WriteLine(value + "|" + md5 + "|" + size);
            }
            sw.Close(); fs.Close();

AB Package browser

It is convenient to check one ab What does the package contain
 Insert picture description here

The yellow one represents being multiple ab Resources included in the package

AB Load asynchronously

Bypass the packaging simulation loading under the editor

if (SimulateAssetBundleInEditor)
			{
    
				string[] assetPaths = AssetDatabase.GetAssetPathsFromAssetBundleAndAssetName(assetBundleName, assetName);
				if (assetPaths.Length == 0)
				{
    
					Debug.LogError("There is no asset with name \"" + assetName + "\" in " + assetBundleName);
					return null;
				}

                // @TODO: Now we only get the main object from the first asset. Should consider type also.
                UnityEngine.Object target = AssetDatabase.LoadMainAssetAtPath(assetPaths[0]);
				operation = new AssetBundleLoadAssetOperationSimulation (target);
			}

Load asynchronously

static public AssetBundleLoadAssetOperation LoadAssetAsync (string assetBundleName, string assetName, System.Type type,string path = "")
		{
    
			Log(LogType.Info, "Loading " + assetName + " from " + assetBundleName + " bundle");
	
			AssetBundleLoadAssetOperation operation = null;
            {
    
                assetBundleName = RemapVariantName (assetBundleName);
				LoadAssetBundle (assetBundleName,false,path);
				operation = new AssetBundleLoadAssetOperationFull (assetBundleName, assetName, type);
	
				m_InProgressOperations.Add (operation);
			}
	
			return operation;
		}

Load dependencies :

  1. load a Generate a AssetBundleLoadOperation, Load for asynchronous operation
public abstract class AssetBundleLoadOperation : IEnumerator
	{
    
		public object Current
		{
    
			get
			{
    
				return null;
			}
		}
		public bool MoveNext()
		{
    
			return !IsDone();
		}
		
		public void Reset()
		{
    
		}
		
		abstract public bool Update ();
		
		abstract public bool IsDone ();
	}
  1. find a All dependence ab package ( for example b,c)
string[] dependencies = m_AssetBundleManifest.GetAllDependencies(assetBundleName);
			if (dependencies.Length == 0)
				return;
				
			for (int i=0;i<dependencies.Length;i++)
				dependencies[i] = RemapVariantName (dependencies[i]);
				
			// Record and load all dependencies.
			m_Dependencies.Add(assetBundleName, dependencies);
			for (int i=0;i<dependencies.Length;i++)
				LoadAssetBundleInternal(dependencies[i], false,path);
  1. hold b,c Add to m_DownloadingWWWs in , use www load
  2. AssetBundleManager in update Judge m_DownloadingWWWs After loading one item , Put in m_LoadedAssetBundles Finished loading ab In the table
  3. stay AssetBundleManager Of Update Middle traversal m_InProgressOperations Every one of them AssetBundleLoadOperation, stay a Of AssetBundleLoadOperation Of update To judge its dependence b,c Are all loaded ( stay m_LoadedAssetBundles Value found in ), All dependencies are loaded , Execute load a Of itself ab Request m_Request = bundle.m_AssetBundle.LoadAssetAsync (m_AssetName, m_Type);
  4. b,c Load... First ,a After loading ,AssetBundleLoadOperation in MoveNext return false, The representative has finished execution , According to ab Package instantiation gameobjec And so on

Synchronous loading

static private AssetBundle LoadAssetBundleSync(string abname, string abPath = "")
        {
    

            AssetBundle bundle = null;
            if (!m_LoadedAssetBundles.ContainsKey(abname))
            {
    
                //byte[] stream = null;
                string uri;
                if (abPath != "")
                {
    
                    uri = abPath + "/" + abname;
                }
                else
                {
    
                    uri = AppConst.AbDataPath + "/" + abname;
                }
                //Debug.Log("Loading AssetBundle: " + uri);

                if (!File.Exists(uri))
                {
    
                    Debug.LogError(String.Format("AssetBundle {0} Not Found", uri));
                    return null;
                }

                //stream = File.ReadAllBytes(uri);

                bundle = AssetBundle.LoadFromFile(uri);
                //stream = null;
                LoadedAssetBundle loBundle = new LoadedAssetBundle(bundle);
          
                m_LoadedAssetBundles.Add(abname, loBundle);

                if (m_Dependencies != null && m_Dependencies.ContainsKey(abname))
                {
    
                    for (int i = 0; i < m_Dependencies[abname].Length; i++)
                    {
    
                        LoadAssetBundleSync(m_Dependencies[abname][i]);
                    }
                }
            }
            else
            {
    
                LoadedAssetBundle loBundle = null;
                m_LoadedAssetBundles.TryGetValue(abname, out loBundle);
                bundle = loBundle.m_AssetBundle;
            }
            return bundle;
        }

About AssetBundle.LoadFromMemroy Memory doubling problem

LoadFromMemroy Even in PC The platform is not as good as LoadFromFile Interface , After testing ,PC On LoadFromMemroy The memory occupation of the interface is probably high 1/5 about , Loading time ratio LoadFromFile The interface is slow 1/5 about , Moreover, such as loy_liu said ,LoadFromMemroy The interface needs to be read first byte[] Array , It can lead to mono Memory allocation , and LoadFromFile Can't .
stay android On the platform , The comparison of memory will be very exaggerated , My test data is close to 3 times .
So don't use LoadFromMemroy Interface ,LoadFromStream The interface does not test its performance and memory , It's said that and LoadFromFile almost .
https://answer.uwa4d.com/question/5e8ed8c6cd6a9b49fb4a46a3

原网站

版权声明
本文为[Sixi Liyu]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/204/202207230540017596.html