Unity Assetbundle Packaging and resource updates

Source: Internet
Author: User
Tags serialization

Unity's Assetbundle packaging is a headache, when I took over the job, I thought that at most only two weeks to the entire package and the resources of the heat update process, the result or spent one months, during the pit countless, summed up hope to save others time.

(a) What type of game project are you in?

Before you start writing a packaged editor script, you might want to look at what type of game project you are playing with in detail first. Is it an end-trip, a hand-tour or a page tour? Because these three are different from the resource management strategy of bundle bundles, if you are publishing across platforms, I suggest you better use macros to switch management policies.

Let me first share the case of two projects that I have taken over from the packaging work.

The first is to migrate from as page to Unity Micro-end of the project, that is, the application environment of the PC, Assetbundle package management is relatively easy, memory is basically casual use. In this case, we used the www to download the Assetbundle package from the Internet, and then use Createfrommemory to build it directly from the memory image, while the background thread writes the resources back to the hard disk.

The second one is a horizontal version of the heavy hand tour, the amount of resources is relatively large. The Android version is close to 300M in the case of all resources put resource

(b) What bundle package loading strategy is used?

Assetbundle loading is available in the following ways:

(1) Createfrommemory/createfrommemoryimmediate

This approach is built directly from memory, can be synchronously asynchronous, can be loaded into memory from the disk through the IO function of C #, and then use this API to build Assetbundle memory image, occupy large memory. Not only is there a built-in assetbundle memory image, but also useful to build the bundle bundle of that part of the managed heap memory byte[], to wait for garbage collection.

Synchronous builds are faster, asynchronous builds are slow, but multiple bundles are built asynchronously at the bottom of unity with optimizations that test faster than one build.

(2) www load

This method is loaded asynchronously into memory, and multiple WWW objects have multi-threaded optimizations. The memory of the managed heap is less than createfrommemory.

(3) WWW.LoadFromCacheOrDownload

This means that the memory is small because unity will open up a space on the hard disk, to cache the Assetbundle after decompression (the main time wasted in extracting this step), and then build the Assetbundle package from this hard disk cache, which takes up less memory, Because the built-in Assetbundle package is primarily a reference to a disk file, the memory that is consumed by the resource is allocated only when it is instantiated. However, the disk cache has an upper limit, which will still become normal after the upper limit is loaded into memory. And you have to have a version number file to manage the incoming version parameters, otherwise it might be loaded into the old assetbundle.

(4) CreateFromFile

Built directly from the hard drive, and only the reference is built, so fast and assetbundle the package itself takes up the least amount of memory. This is recommended because the synchronous code is better written, especially when the bundle mechanism is referenced later in the project, and it is too much to load all the previous resources into an asynchronous logic.

(iii) Load resources from built-in Assetbundle

Assetbundle.load/assetbundle.loadassetasync

The upload of textures on the PC takes place in this step. I tested a 1024*1024 texture upload time is often 10 times times the upload time of 512*512, so reducing the texture size is the most cost-effective optimization. For 2d MMORPG often used large figure 2048*2048, if you use synchronous load a multi-frame animation, you can obviously feel the card. If using async does not drop frames at all, it is estimated that unity uses sub-image to lock a small area of texture at once to upload the graphics card, but it is slow and there is no way to adjust which parameters to speed up this step. Like a large 2d micro-terminal, the need to load many large images in real time on the scene is unsatisfactory and can be optimized in a transduction way.

There are also unity objects that take a long time to build, and many games are too long to be built and instantiated by prefab. You can use the pool manager way to save the instantiated objects, pass the card only to unload its memory of large-size texture sound and other resources, the next time you need to add back. This can greatly reduce the time of the card, but this way will give Assetbundle management to bring some trouble, I will be in the back bundle package uninstall there mentioned.

Four Assetbundle Packaging

(1) Dependent packaging

The most headache is this step, you have to consider how to deal with the dependencies between resources, to avoid the generation of resource redundancy. Unity provides pushdependencies and popdependencies to handle the shared resource issues of dependent packages, such as the following dependencies you have

(A, B)->c->d

The package script is

Push

Build D

Push

Build C

Push

Build A

Build B

Pop

Pop

Pop

This is a stack structure, after the resources of the stack if there is a first-in-the-stack resources, it will not be re-packaged in, but rely on the package. When loading, make sure to load the dependent packages before loading the last package. But is dependent on the package can be loaded in random order, if you use the WWW load, you can consider a few www plus.

And you have to figure out the dependencies that are set when Pushdependencies/popdependencies is packaged and the dependencies that are loaded when they are not the same thing, and this is where I started to get confused. For example, you have the following dependency structure

A-> (B1 B2 B3 B4)->c

D-> (B3,B4,B5,B6)->g

Then your packaging script should look like this.

Push

Build C,build G

Push

Build B1,b2,b3,b4,b5,b6

Push

Build A,d

Pop

Pop

Pop

It looks as if both A and d are dependent on B1-B6, but it's not, so packing out a and D packages will only depend on the packages that contain the same resources, such as when you load the D package, you just need to load the B3-B4 as long as your package parameters are set correctly, and when B1,B2 changes, The D-pack binaries that are packaged in this process are still unchanged.

(2) Parameter setting when packing

Buildassetbundleoptions.deterministicassetbundle

This parameter is set for each package to ensure that the binary does not change, as long as the dependent package does not change, the packaging process does not change. So to do the resource update, this parameter is not small, otherwise the resource does not change the circumstances of the repeated packaging out of the MD5 are different, how to ensure the normal update function?

Buildassetbundleoptions.collectdependencies

This parameter is used to collect all dependent packages, although we will manually collect the dependencies for Push/pop dependencies, but still need to add this parameter because you will not collect all the resources that a package relies on, you will only push a few resources that it depends on. Then use the collectdependencies to hit the final package and make sure that all the resources that the package relies on are in.

Buildassetbundleoptions.completeassets

Force the entire resource to be included

Buildassetbundleoptions.uncompressedassetbundle

Packaging a bundle package in an uncompressed manner

These four parameters are used when we pack, and only the last parameter depends on the situation.

(3) Collecting dependencies

Use Assetdatabase.collectdependencies to traverse all of the resources before packaging to collect their dependencies, and at the end of the package they are graded according to the depth of each resource being relied on, first packing a lower level, such as shader, Script these resources are dependent on other resources but do not depend on other resources, with the lowest level. Such as prefab relies on all previous resources, the highest level, placed in the last package. Generally according to the type of resource (Prefab,mesh,animator,texture,script ...) Be graded. Even if this is done by type, it is not enough because resources at the same level can also have interdependent relationships. For example, using Ngui, a panel prefab relies on a few uiatlas prefab, and this sibling dependency needs to be sorted by depth-first traversal to determine dependencies. This dependency is recorded using a serialization file, which loads all the dependent packages used when the package is loaded later. Each time the update is updated, the serialization file for this dependency is also updated with other resources.

(4) Some problems that may be encountered when packing

If you use Www.LoadFromCacheOrDownload, please call ClearCache at the beginning of the game when debugging. Even if your code has a mechanism for dynamically updating the version parameters passed in Loadcache, be cautious when debugging, and if the bug causes you to pass the same version as the last time, the dependent package cache versions do not match, which can cause some outlandish problems.

Check that the dependency structure that your packaging process records is stable. The stability here refers to the collectdependencies when there is no processing of the dependent resources, it is possible to package the same resources at the time of mutual eating resources. Like what

A-> (B c)->d

E-> (F c)->g

Packaging scripts

Push

Build D,g

Push

Build B,f

Push

Build A,e

Pop

...

When it comes to collecting dependencies, C is a resource that we ignore, when packing B and f at the same level, A and e at the same level, because the use of the Collectdependencies,a package will take C, but because the B package at the same level with a hit, will appear C hit a to no longer hit the B, but you load B did not load A, so B is not working properly.

The way to troubleshoot this bug is to first play one or two roles or panels, back up, and then hit all the resources. Compare two resources with binary tools (recommended Beyondcompare, can be compared to the directory), if there is an unstable structure can be found immediately.

And the width of the texture. Use a multiple of 2, and when I test an irregular graph, I find unity has a temporary resource for this graph that generates a fmt-512*512 (sprite), which is not available when the resource get his hard drive address, so it is not logged into the dependency file. When there are two graphs are not standardized, a bundle package of a graph contains temporary resources another picture is not, loading out will not be normal. Of course, the general game project in order to optimize the use of the diagram are more standard, will not encounter this problem.

Another problem is the use of the Mechanim animation system. The Assetbundle package will appear the animation system does not work properly, in the inspector display "Animator is not initialized". When I searched the Internet, I found that a lot of people had this problem, and some say that unity 4.6 solved the problem, some say 5.0. I began to think that only by loading the character prefab from the Assetbundle package, and then loading the animated file from Resouce Overrideanimcontroller attached to prefab to solve ( Prefab can modify the script it hangs on before it is instantiated). But this loses the meaning of the hot update. I later found that the Anim file to be a separate package, controller files to a separate package, rely on their prefab again into a package, in the packaging when the editor will be warned that "can not put the editor object into the bag", But it is normal to load out a group of packages that have been punched in this way. If I use Collectdependencies to let controller files automatically included in the role pack, the role of the play will still appear "Animator is not initialized" problem. It may not be the reason, it may be that I have been troubleshooting the "mutual eating resources" bug when not cleaned up, do not know if anyone has encountered the same problem.

(v) Update mechanism

Update mechanism is relatively simple, collect all bundle package MD5 code and file size, make a list. In the game before the game version number prompts to update the game program, and then the resource version number, if the new version is found to start downloading the MD5 list, and the local MD5 list to compare, find the resources that need to be updated with HTTP download on the line.

This process still has a lot of things to consider, such as your HTTP download to download the failure to retry a few times the mechanism, to have time-out detection, you need to know when to download which resources when the entire update process stuck, logging. Even if there is an error in the update process, the next time the updated resources are not repeated updates, so it is best to write back 10 resources per update MD5, rather than the full and then write back.

MD5 list comparison, the previous PC game will be at the far end of the comparison with the previous version, and then generate a ver x to ver x+1 resource update files. At the time of the update if the game's resource version number is ver x-1 download the resource update file update for ver x first, and then update from Ver x to ver x+1. But this set of use in Unity Mobile resources update on the risk, assuming some mobile phone cleanup software prompted the program's resources occupy too large, accidentally led to clear some of the resources, but your ver x file is still in, then you update when the part of the resource is cleared out. So it is more prudent to compare all MD5 on the client side at the same time, when extracting one item from the local MD5 list and also detecting whether there is a local resource file, and not adding the updated list, so that the resource can be retrieved even if it is accidentally cleared.

(vi) Compression bundle package

Because we are using the Createfomefile synchronization mechanism to load the package, and CreateFromFile can only use Buildassetbundleoptions.uncompressedassetbundle, Pack it up and unzip it when you update it. Therefore, the use of what compression algorithm is a debatable issue.

Compression you have to consider two aspects: Compression ratio and decompression time.

adjourned

(10) Assetbundle Package Offload

Unity Assetbundle Packaging and resource updates

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.