Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Example Analysis of objects and Serialization in Unity

2025-02-21 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/01 Report--

Editor to share with you the example analysis of objects and serialization in Unity, I believe that most people do not know much about it, so share this article for your reference, I hope you can learn a lot after reading this article, let's go to know it!

1.1. In-depth understanding of resources and objects

Before you understand how Unity ensures the foolproof management of data, you need to know how Unity recognizes and serializes the data. The first point is to correctly distinguish between resources (Asset) and objects (UnityEngine.Objects).

Asset

Resources (Asset) are files on your hard disk that are stored in the Assets folder of the Unity project. For example, textures (Texture), materials (Material), FBX files, and so on, are resources. Some resources have data formats that are natively supported by Unity, such as materials. Some resources, such as FBX files, need to be converted to native data formats before they can be used by Unity.

UnityEngine.Object

UnityEngine.Object, or Object-- objects that begin with an uppercase O, represent a collection of serialized data, representing a specific instance of a resource. It can be any type of resource used by the Unity engine, such as grids, Sprite, audio clips, or animation clips. All objects (Object) are subclasses of the UnityEngine.Object base class.

Special Object type

Almost all Object types are built-in, of which there are two more special types.

ScriptableObject provides a convenient system for developers to customize data types. These types can be serialized or deserialized directly by Unity and manipulated in the viewer window of the Unity editor.

MonoBehaviour provides a container for linking to MonoScript. MonoScript is an internal data type that Unity uses to hold references to specific script classes in a particular assembly and namespace, and MonoScript itself does not contain any actual executable code.

One-to-many relationship

There is an one-to-many relationship between Asset and Object, that is, a resource file may contain multiple Object.

1.2. References between objects

All UnityEngine.Objects can reference other UnityEngine.Objects. Here "other Object" may exist in the same resource file or need to be imported from another resource file. For example, a material Object usually has a reference to one or more texture Object. These texture Object are typically imported from one or more texture resource files (such as PNG or JPG files).

After serialization, these references consist of two parts of data: the file GUID and the local ID. The file GUID is used to identify the storage location of the target resource (Resource) in the resource (Asset) file. The locally unique (1) ID is responsible for identifying the Object in a single resource file, because a resource file may contain multiple Object.

File GUID (.meta)

The file GUID is stored in a .meta file. Unity generates a .meta file when it first imports the resource file and stores it in the same directory as the resource file.

The above identification and reference system can be viewed using a text editor:

Create a brand new Unity project, change the editor settings, set Version Control in Edit-Project Settings-Editor to Visible Meta Files, and set Asset Serialization to text.

Create a new material and import a texture into the project. Assign a material to a cube in the scene and save the scene.

Use a text editor to open the .meta file for this material. Near the top of the file, there is a line labeled "guid" that defines the file GUID of the material resource file.

FileFormatVersion: 2guid: 6839b719d14310c4f945de352bac3767timeCreated: 1472566765licenseType: ProNativeFormatImporter: userData: assetBundleName: assetBundleVariant: local ID (specific file)

To view the local ID, open the material file using a text editor, and the definition of the material Object is roughly as follows:

YAML 1.1%TAG! U! Tag:unity3d.com,2011:---! upright 21 & 2100000Material:serializedVersion: 6. More data...

In the above example, the number preceded by the & symbol is the local ID of the material. If the Object of this material is in a resource file with the file GUID "abcdefg", the only identifier for the material Object is the combination of the file GUID "abcdefg" and the local ID "2100000".

1.3. Why use file GUID and local ID? Work flow

In Unity, why use the file GUID and local ID systems? The answer is not only to serve for stability, but also to provide a flexible workflow independent of the specific platform. The file GUID provides an abstraction of the file storage location, so that a file GUID corresponds to a specific file, and it doesn't matter where the specific file is stored. So we can move the file at will without breaking all relevant Object references to the file.

Any Asset file may contain (or generate by import) multiple UnityEngine.Object resources (Resource), so you need a local ID to make a clear distinction between the Object in it.

If the file GUID associated with the resource file is lost, all references to the Object in that resource file are broken. This is why you must ensure that the .meta file has the same file name as the resource file and is stored in the same directory. Note that Unity regenerates missing or deleted .meta files.

The Unity editor maintains the mapping table

The Unity editor is responsible for maintaining a mapping table of the relationship between the file path and the file GUID. As long as the resource file is read or imported, this mapping is established, and the mapping associates the specific location of the resource with the resource's file GUID. When the Unity editor is open, assuming that the .meta of a file is accidentally lost and the path of the resource file has not changed, the editor can guarantee that the resource will be assigned to the same file GUID.

If the .meta file is lost while the Unity editor is closed, or if the resource file is moved but not the corresponding .meta file, all references to the Object in the resource file are lost.

1.4. Composite resource and importer resource importer

As mentioned in the previous in-depth understanding of resources and objects, resource types that cannot be directly supported by Unity must be imported before they can be used-- using the resource importer. These importers are called automatically, or you can use AssetImporter to call API and its subclasses in the script. For example, when importing individual texture resources such as PNG and JPG, TextureImporter API provides access to the relevant settings to be used on import.

The final product of the import process is a series of UnityEngine.Object. In the Unity editor, these objects are represented as multiple child assets under the parent asset, such as texture materials imported as Sprite Atlas, whose subordinates have multiple nested Sprite. Each object uses the same file GUID because their source data is stored in the same resource file. The specific distinction between them in texture resources is done by local ID.

Library folder

During the import process, the source resource is converted to a format that matches the target platform selected in the Unity editor. The import process may involve some heavyweight operations, such as texture compression. It would be too inefficient to perform these operations every time you open the Unity editor.

To solve this problem, we cache the results of the resource import in the Library folder. Specifically, the results of the import process will be stored in a folder with the first two digits of the resource file GUID. These folders are located in the Library/metadata/ directory. Different objects are serialized and stored in a binary file named using the GUID of the resource file.

This is the same for all resources, not just non-native resources. It's just that resources natively supported by Unity do not need to be transformed or serialized.

The first part mainly introduces the difference between Asset and UnityEngine.Objects, as well as the relationship and difference between file GUID and local ID. The second half will introduce you to the third ID: the object instance ID, and see how these ID affect the loading and unloading of resources in memory and video memory, respectively.

1.5. Serialization and instance instance ID

Although the file GUID and the local ID are ready to strongly maintain the relationship between resources, there is another problem, GUID is relatively inefficient, and we need to prepare a more efficient solution for the runtime. Unity internally maintains a cache table (2) that converts the file GUID and the local ID into integer values that are unique in this session and are called instance ID. The instance ID is simply allocated to newly registered objects in the cache in a monotonously incremental manner.

The cache is responsible for maintaining the mapping of the instance ID to the source data location of the object defined by the file GUID and local ID, as well as the address of the object in memory, if any. In this way, Unity can strongly guarantee their reference relationship to each other. By parsing the instance ID, we can quickly find and return the loaded instance corresponding to ID. If the target is not loaded, Unity obtains the source data of the object through file GUID and local ID parsing, and loads the object in real time.

At startup, the instance ID cache is initialized with all built-in objects in the project (such as referenced in the scene), as well as all objects under the Resources folder. If new resources are imported or new objects are loaded from AssetBundle at run time (3), the cache is updated and entries are added for those objects. The instance ID is removed from the cache only when it expires, and a removal operation occurs when the AssetBundle that provides the specified file GUID and local ID is uninstalled.

Uninstalling AssetBundle invalidates instance ID, and the mapping between instance ID and its file GUID and local ID is removed to save memory. After reloading AssetBundle, each loaded object gets a new instance ID.

For a more in-depth discussion of AssetBundle implicit unloading, refer to the section on managing loaded resources in AssetBundle Usage Patterns.

Considerations (pending status on IOS)

Note that on some platforms, there are system events that cause objects to be forcibly unloaded in memory. For example, on iOS platforms, when an app is suspended, graphics resources are unloaded from video memory. If these objects are from a dismounted AssetBundle, Unity will not be able to load them again from the source data. Any existing references to these objects will be invalidated. In this example, the result is that the mesh is invisible (missing), or the texture and material of the model is magenta (missing Shader).

Prompt

Tip: at run time, the description of the above control flow is not completely accurate. The comparison of the file GUID and the local ID is also less efficient when the load is heavy. When you build a Unity project, the files GUID and local ID are mapped to a simpler format, to be exact. However, the concept is roughly the same, and it makes some sense to consider the way the file GUID and local ID work when considering the "runtime".

This is why the file GUID of the resource cannot be fetched at run time.

1.6.MonoScripts

It is important to understand MonoBehaviour to know that it has a reference to MonoScript. The purpose of MonoScript is very simple, including the information needed to locate a specific programming class. Neither of these objects has executable code for the program class.

A MonoScript contains three strings: library name, class name, and namespace.

Library (dll)

When you build the project, Unity collects separate script files in the Assets folder and compiles them to form a Mono library. In particular, Unity compiles the languages in the Assets directory separately, as do the scripts in the Assets/Plugins directory. C # scripts outside the Plugins subdirectory are placed in Assembly-CSharp.dll. Scripts in Plugins and its subdirectories are placed in Assembly-CSharp-firstpass.dll, and so on.

These libraries (plus the precompiled DLL libraries) will be included in the final built Unity application. These libraries are all referenced by MonoScript. Unlike other types of resources, all applications in a Unity application are loaded the first time the program starts.

MonoScript is why the MonoBehaviour component in AssetBundle (or a scenario, a Prefab) does not contain any actual executable code. This allows different MonoBehaviour to refer to a shared class, even if the MonoBehaviour is not in the same AssetBundle.

1.7. Resource (Resource) life cycle

The point in time at which UnityEngine.Objects is loaded or unloaded from memory is defined. In order to shorten the program loading time and manage the memory footprint of the application, it is important to understand the resource life cycle of UnityEinge.Object.

Two ways to load UnityEngine.Object

There are two ways to load UnityEngine.Object: automatically or externally.

When the instance ID of the object is dereferenced from the object itself, the object is not currently loaded into memory and can be located to the source data of the object, and the object will be loaded automatically. Objects can also be loaded externally, by creating objects in a script or by calling a resource load API to load objects (such as AssetBundle.LoadAsset).

After the object is loaded, Unity attempts to repair any possible reference relationships by converting each referenced file GUID and local ID into an instance ID.

Once the instance ID of the object is dereferenced and meets the following two criteria, the object will be forcibly loaded:

The instance ID refers to an object that is not loaded.

The instance ID has a corresponding valid GUID and local ID in the cache.

This usually occurs shortly after the reference is loaded and parsed.

If the file GUID and local ID do not have an instance ID, or if an instance of an unloaded object ID references an illegal file GUID and local ID, the reference itself is retained, but the actual object is not loaded. Appears as a "(empty)" reference in the Unity editor. In a running application, or in the scene view, "(empty)" objects are usually represented in a variety of ways, depending on the type of missing object: the mesh becomes invisible, the texture appears magenta, and so on.

Three cases in which an object is unloaded

The object is unloaded in the following three cases:

After the idle resource cleanup process starts, some objects are unloaded automatically. This process is usually triggered automatically when the scene switch does not retain the original scene (for example, the non-superimposed scene switching API Application.LoadLevel is called), or when Resources.UnloadUnusedAssets is called in the script. The process unloads only objects that are not referenced: objects are unloaded only if there is no reference to it in the Mono variable and no other active objects that reference the object.

Objects in the Resources directory can be unloaded actively by calling Resources.UnloadAsset API. After uninstalling, the instance ID of the object remains available, and entries for the file GUID and the local ID are retained and still valid. If a Mono variable or other active object pointing to that object references an object that is unloaded by Resources.UnloadAsset, the object will be reloaded as soon as any valid reference is dereferenced.

When AssetBundle.Unload (true) API is called, objects loaded from AssetBundle are automatically unloaded immediately. This operation releases the file GUID and local ID references of the object instance ID, and any reference to the unloaded object becomes a "(null)" reference. In a C # script, any attempt to access methods and properties on an unloaded object will result in a null reference exception (NullReferenceException) thrown.

If AssetBundle.Unload (false) is called, objects that are still active in the unloaded AssetBundle will not be recycled, but Unity will release the file GUID and local GUID references of its instance ID. If they are then unloaded from memory, leaving only references to these unloaded objects, Unity cannot reload these objects again (4).

1.8. Load a large structural tree (Hierarchies)

When serializing a structure tree that contains a large number of Unity game objects (such as serializing Prefab), keep in mind that the entire structure tree is fully serialized. That is, each game object and component in the structure tree is represented separately in the serialized data. This will have an interesting impact on the loading and instantiation time of the game object structure.

Assuming that a code block instantiates a certain number of game objects, the instantiation of a single Prefab with a very large structure tree takes more CPU time than instantiating multiple modules of the structure tree separately and then combining them at run time.

After an in-depth analysis of the underlying data, it is found that the CPU time taken to instantiate and wake up game objects is roughly the same in all cases, and that the instantiation and wake-up of a single independent Prefab takes only a very small amount of CPU time (because tranmpolining and SendTransformChanged callbacks are not required). However, these small time savings are not worth the time spent reading and serializing data.

As mentioned earlier, when you serialize a separate Prefab, each game object and its components are serialized separately-even if the data is duplicated. In a UI interface with 30 separate elements, Unity serializes those elements 30 times, resulting in a large amount of serialized data. When loading, all 30 repeating elements of the game objects and components need to be read from the hard disk before being converted to a new instance object. It is the read time discussed here that determines the performance cost of instantiating a large Prefab.

After Unity supports nested Prefab, for projects that need to load large structured game objects, to reduce the loading time of such projects, consider storing reusable elements in large Prefab into different Prefab separately and instantiating them at run time, rather than relying entirely on Unity serialization and Prefab system.

Footnotes (footnote)

The local ID is unique in the file. That is, in a resource file, the local ID contained in it is not duplicated.

Internally, this cache is called PersistentManager. The actual conversion is done in the C++ Remapper class of Unity, which does not provide any C # API calling interface.

An example of creating a resource at run time is to create a Texture2D object in a script: var myTexture = new Texture2D (1027)

When an object is removed from memory without being unloaded at run time, it usually occurs when Unity loses control of the content of the drawing. For example, when a mobile app is suspended and forced to run in the background. In this case, the mobile operating system usually forcibly unloads all graphics resources from the GPU video memory. When APP then returned to the foreground to run, Unity had to re-upload the required materials, shaders, and mesh data to GPU in order to restore normal rendering of the scene.

This is all the content of the article "sample Analysis of objects and serialization in Unity". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report