Unity Performance Optimization Methods (not original)

Resource separate packaging and loading

  The game will be a lot of places use the same resources. For example, some share the same interface of a font, with an atlas, a map and some share the same scene, some monsters use the same Animator, and so on. These common resources when creating game isolated from other sources installation package out, packaged separately. For example, if resource A and B both refer to a resource C, C will separate out to make a bundle. In the running game, if you want to load A, C is loaded first; then if you want to load B, C as an example has been in memory, so long as the direct loading B, B to point C to make. If C does not separate from the package out of A and B, then there will be a C A bag, the bag will have a C B, C redundant installation package will stretch; and at runtime, if a and B are loaded into memory, the memory will have two instances C, increased memory footprint.

  Loading the resource separation packing is the most effective means for reducing the volume of the operation when the packet memory footprint of the installation. Usually the finer particle size package, the less the two indicators; and when two adjacent DrawCall renderQueue using the same texture, and the material shader instances, the two can be combined DrawCall. Packaging is also fine but not the more the better. If you want to run while loading a large number of small bundle, then the speed will be very slow to load - time wasted in scheduling between coroutines and small batches of I / O up; and DrawCall merger will not necessarily improve performance, sometimes it will reduce performance, will be mentioned later. There is a need to strategically control pack size. Generally larger fonts and textures of this volume public resources.

  A resource that can be used AssetDatabase.GetDependencies use what other resources.

2 Map transparent channel separation, compressed format to ETC / PVRTC

  Initially we used the map as DXT5 compression format, hoping to reduce texture memory footprint, but soon discovered that the mobile platform graphics card is not supported. So for a 1024x1024 sized RGBA32 maps, although DXT5 before it can be compressed from 4MB to 1MB, but it will be sent to the graphics card, CPU will first use in memory unpack it into 4MB of RGBA32 format (decompression software), this is then sent to 4MB of memory. So at this time, this map will take up 5MB of memory and 4MB of video memory; and mobile platforms are often not independent memory, required to pull one from memory as video memory, so thought only 1MB of memory map actually accounted for 9MB !

All hardware does not support extracting compressed format have this problem. After some research, we found that the Android hardware support is the most widely used format ETC, Apple is PVRTC. But both formats are not with transparent (Alpha) channel. Therefore, we will each original texture transparent channels are separated out and written into the red channel in another map. These two maps are used ETC / PVRTC compression. When rendering, the two maps are sent to memory. We modified the NGUI the shader, when rendering the second map of the red channel writes transparent texture in the first channel, restore the original color:

fixed4 frag (v2f i) : COLOR  

    fixed4 col;  

    col.rgb = tex2D(_MainTex, i.texcoord).rgb;  

    col.a = tex2D(_AlphaTex, i.texcoord).r;  

    return col * i.color;  

fixed4 frag (v2f i) : COLOR

{

    fixed4 col;

    col.rgb = tex2D(_MainTex, i.texcoord).rgb;

    col.a = tex2D(_AlphaTex, i.texcoord).r;

    return col * i.color;

}

In this way, 1024x1024 RGBA32 size of the original map a 4MB, it will be compressed into two separate and 0.5MB of ETC / PVRTC map (we use the ETC / PVRTC 4 bits). Memory usage when they render is 2x0.5 + 2x0.5 = 2MB.

3 Close map reading and writing options

Unity is introduced into each texture has a read-write (Read / Write Enabled) switch enabled, the corresponding parameter is a TextureImporter.isReadable. When you select the map you can see this switch in the Import Setting tab. Only open the switch, it can be used to map Texture2D.GetPixel, read or rewrite pixel map resources, but which requires the system to retain a copy of the map in memory, for CPU access. General game will not have such a demand is running, so we have closed this switch on all maps, but maps do in editing after import processing (such as the separation of the original texture transparent channel) and turns it on. Thus, the size of 1024x1024 texture mentioned above, its runtime memory footprint of the 2MB and can be less than half, is reduced to 1MB.

4 to reduce the number of scenes GameObject

  One time we will reduce the number of GameObject scene of nearly 20,000, the game memory usage on iPhone 3S flew reduction of 20MB. Although these basic GameObject is hidden (activeInHierarchy is false), but will still take up a lot of memory. These GameObject who also mounted a lot of scripts, each script must GameObject each instantiation, but also a lot of money than the memory footprint. So then we specified number GameObject scene not more than 10,000, and the number of GameObject as a weekly version of the performance monitoring indicators.

Atlas 5

  The main purpose of finishing atlas is to save runtime memory (although sometimes also can play a role in the merger DrawCall). From this perspective, the display memory is fed when the sum of the sizes a portfolio interface is as small as possible. Generally there is a method that can help us do that:

  1) in the interface design, will try to make art controls designed to make squares stretch that UISprite of type Sliced. Such art can only cut out a small map, we pulled it big in the Unity. Of course, the controls do a squared means that the number of vertices from four to at least 16 (the center of the grid squares tile type using Tiled do so, the number of vertices will be more), build overhead DrawCall will be even greater (see point 6), but generally as long as DrawCall be reasonable (see also point 6) will have no problems.

  2) at the interface is also designed as far as possible the art form a symmetrical pattern design. FIG thus cut when only a portion of art can be cut, we will spell out the complete pattern Unity. For example, a circular pattern, can be cut only a quarter of the art; for a face, can only be cut out half of the art. However, the point 1) Similarly, this method also has the expense of other properties - the number of vertices and a pattern corresponding to the number GameObject are increased. Point 4 already mentioned, an increase in the number of GameObject sometimes significantly more memory. So this method generally employed for larger-sized pattern.

  3) Be sure not to unnecessarily map material memory-resident, not when rendering irrelevant the map material sent to memory. This requires a separate interface in accordance with Atlas, Atlas just put a general interface of a material, a interface UISprite do not use Atlas other interface. There is a little on the assumption exactly the same interface A and B gold icon interface, not because the sake of convenience in the production of, let's UISprite interface A direct reference to gold in the B material interface; otherwise, when the interface A display will Atlas entire interface B are also sent to memory, but is still in memory as long as a, B Atlas also resident in memory. In this case, it should be concentrated in each of panels A and B of an identical icon put coins, only UISprite A in the atlas A, B of the B UISprite only portfolio.

  However, if there are a lot of the same material between the two interfaces, the two share the same interface can be a atlas. This will reduce the total memory footprint of all interfaces. It needs to be weighed against art design specific operation. The more general the same common interface between the material, the less the burden of program memory. However, the interface between the same thing too much, the effect may not be vivid art, this is the place between art and procedures and a need to seek balance.

  In addition, a large number of icons resources (article icon) not to do in the atlas in, and should be used UITexture.

4) reduce the blank space diagram set. Figure concentrate fully transparent pixels and pixel memory space occupied by impervious name is actually the same. Therefore, when the same amount of material, to minimize atlases blank. Sometimes a 1024x1024 of atlases, material area not occupied by more than half, then we can consider this Atlas Atlas will cut two of 512x512. (Some people may ask why not make a 1024x512 Atlas, which is required because the iOS platform seems to be sent to the memory map must be square.) Of course, two different Atlas DrawCall can not be merged, but this is not What is the problem (see point 6).

  It should be said, finishing Atlas in the specific operation and no hard and fast criteria, often need to be weighed against the final decision on how to organize, because no matter what kind of measures will have another performance cost.

8 lower resolution textures material

  The trick that white is actually reduce the size of the texture of the material. For example, for an original painting size is 100x80, we will put it down to 50x40, that is, after it twice reduced import Unity. The game is actually used map after narrowing. But this move is bound to significantly reduce the quality of art, art will immediately find the picture becomes more blurred, it is generally less than the program barely time will not be used.

9 interface lazy loading and unloading the timing strategy

  If some of the interface less important, and do not often use, you can wait until the interface needs to turn on the display when it is loaded from resource bundle, and when you close the unloading out of memory, or wait some time before you uninstall. But this approach has two costs: First, it will affect the experience when players asked to open interface, display interface will be delayed; the second is more susceptible to bug, the upper asynchronous write logic to consider the case, when a programmer to access interface when, this interface may not be in memory. So far we have yet to implement the program. When present, just enter a new scene, a scene used to uninstall the new scene but does not use interface.

  More than nine method, 4,5,6 required from the planning point of view of art and the problem to some extent, and the need to continue to maintain surveillance in order to maintain an optimal state (because there will always be new interface design requirements or changes demand old interface); the other is a permanent solution, as long as the implementation of stable, will not have to spend energy on it. However, both methods 2 and 8 will reduce the quality of the art, especially 8. If you reduce the quality of fine arts degree really can not endure, it may not allow the use of these two methods.

10 Avoid frequent calls GameObject.SetActive

Some of our games would frequently call in a logical frame GameObject.SetActive, show or hide some objects, the number reached a hundred times as much. CPU overhead of such a large operation (especially NGUI of UIWidget activated when initialization will do a lot of work), and will trigger a lot of GC. Then we changed the display and hidden object approach - let the object remains active (activeInHierarchy is true), and the original SetActive (false) instead move an object offscreen, SetActive (true) changed the object back within the screen. Such performance was much better.
----------------
Disclaimer: This article is CSDN blogger "Hus Dian zZ 'original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source and link this statement.
Original link: https: //blog.csdn.net/qq_35037137/article/details/89851113

Guess you like

Origin www.cnblogs.com/-831/p/12098658.html