Assets and objects
Asset is a file stored on your hard disk and saved in the Assets folder of your Unity project. For example: texture maps, materials, and FBX are all assets. Some assets save data in unity native format, such as a material. Other assets require processing to convert to native formats, such as FBX.
Object is a series of serialized data that describes a specific resource instance, which can be any type of resource used by unity, such as Mesh,sprite,audio clip or animation clip. All objects are subclasses of Unityengine.object.
Most of the object types are built in unity, but there are two special types:
1. Scriptableobject allows developers to define their own data types. These types can be serialized and deserialized by unity and manipulated in the inspector window of the editor.
2. Monobehaviour provides a package that is linked to the monoscript. Monoscript is the internal data type of unity, which holds references to specific script classes in specific assemblies and namespaces. The monoscripte does not contain any actual executable code.
There is a one-to-many relationship between assets and objects: in other words, the asset file can contain a single or multiple objects.
Internal object reference
All unityengine.objects can refer to other unityengine.objects, the referenced Objects can be in the same asset file as the referenced Objects, or it can be imported by other asset files. For example, a material object typically has a reference to one or more texture objects, which are typically imported from a texture resource file (such as PNG or JPG).
When serialized, these objects consist of two separate pieces of data: The GUID of the file and the local ID. The GUID of the file marks the asset file where the resource is stored. Local IDs are locally unique (that is, in each asset file, the local ID is unique), and each object in the asset file is marked.
The GUID of the file is stored in the. meta file. These. Meta files are generated when unity is first imported into assets, and are stored in the same directory as asset. Diffuse materials and their. Meta files are shown:
The. Meta file contains the GUID:
Open the material file itself and you can see the local ID:
If you have objects in your scene that are rendered using that material, then when you open the scene file, you will notice that the material object is tagged with a GUID and a local ID:
Why use GUIDs and local IDs?
The function of the GUID is to provide an abstract representation of the file path. The location of a file on disk is irrelevant whenever a specific file is associated with a GUID. As a result, you can move the file arbitrarily without needing to update the objects that references the file (because these objects store the file's GUID).
Because a asset file may contain multiple Unityengine.object resources, each different object needs to be clearly marked with the local ID.
If the GUID of an asset file association is missing, all references to objects in the asset file are lost. Unity is regenerated when the. meta file is lost.
Unity maintains a mapping between specific file paths and GUIDs. When a asset is loaded or imported, a new mapping entry is added that connects the asset file path to the GUID of the asset file. If a asset. meta file is missing but its file path does not change, unity can ensure that the GUID recorded in the regenerated. Meta is unchanged.
If the. Meta file is lost when unity is closed, or if the path to the asset file changes, but the. meta file does not move along with it, all references to objects in the asset file are lost. For example, the cube in the scene uses the material I created diffuse:
Diffuse materials and their. Meta files are stored in the assets directory, and if you now move the diffuse material externally to the Assets/temp directory, the cube will lose its reference because it does not move its. meta file at the same time:
Resources and their import
Non-Unity native resources must be imported into unity for use, which is done through asset importer. These improter are automatically invoked when the resource is imported, and you can also use the API of Assetimporter and its subclasses to adjust the resource import process through code.
The result of a resource import is one or more unityengine.objects. In unity you can see that a parent object contains multiple child objects, such as the Sprite Atlas:. These objects share the same GUID because their source data is from the same asset file. Unity uses the local ID to differentiate them:
The resource import process involves time-consuming operations, such as texture compression. So it would be very inefficient to open unity every time the resource import process is performed, so unity caches the results of the resource import in the Library folder:. Specifically, these folders are stored in the folder named before the GUID of the asset file, which is located in directory Library/metadata:
In fact, even the Unity native resource will store the import results in the corresponding file. However, native resources do not require a long conversion time or re-serialization time.
Instance ID
Although GUIDs and local IDs are robust, the comparison of GUIDs is time-consuming, and we need a very efficient system at runtime. So unity maintains a cache internally, which converts GUIDs and local IDs into unique integers, called Instance IDs, which are assigned in a simple, monotonically incrementing manner whenever a new objects is added to the cache. The cache maintains the mapping between the instance id,guid and local IDs (which are the two locations on disk where the source data that defines the object) and the object's in-memory instances (if object has already been loaded into memory). In this way, unityengine.objects can maintain the referential relationship between each other. The instance ID allows you to quickly find the corresponding object that has already been loaded, and if the corresponding object has not yet been loaded, you can find the source data of the object with the GUID and local ID, and then load the corresponding object.
When the application starts, data for the project's built-in objects (such as objects used in the scene) and the data for objects in the resources folder are initialized to the instance ID cache. A instance ID entry is added to the cache when a new resource is imported (such as a Texture2d object created by script) at run time, and when an object is loaded from Assetbundle. The Instance ID is removed from the cache only if it is considered obsolete, which occurs when a assetbundle is unloaded. When a assetbundle is unloaded, the mapping data between the Instance ID and the GUID and the local ID is removed from memory in addition to causing the corresponding Instance ID to be considered obsolete. If Assetbundle is reloaded, then each object loaded from the Assetbundle will create a new instance ID.
It is important to note that some specific events on the specific platform cause objects to be removed from memory. For example, when an application on iOS is suspended, the graphics resources may be removed from the video memory, and if the resources are from a assetbundle that has been uninstalled, then unity cannot reload the resources. Any references to these resources will also become invalid (for example, an invisible model (missing) is rendered using a pink material (missing)).
Monoscript
A monobehaviour contains a reference to Monoscript, and Monoscript contains only the information needed to navigate to a specific script class that does not contain executable code for the script class.
A monoscript contains three strings: An assembly name, a class name, and a namespace name.
When Unity builds the project, all the script files under the Assets folder are compiled into the mono assembly. Specifically, Unity compiles an assembly for each of the different programming languages used in the Assets folder, and the scripts in the Assets/plugins folder are compiled separately into one assembly. C # Scripts outside of the Assets/plugins folder are compiled into Assetmbly-csharp.dll, in assets/ Java scripts outside the plugins folder are compiled into Assembly-unityscript.dll, and scripts in Assets/plugins are compiled into Assembly-csharp-firstpass.dll.
These assemblies, together with the precompiled Assembly, are included in the final application:
These assemblies are the assemblies referenced by Monoscript. Unlike other resources, all assemblies are loaded when the application is first started. This approach is also why an assetbundle (or a scene, a prefab) does not contain executable code in the mounted Monobehaviour component. This approach allows different monobehaviour to refer to a common, concrete class.
Resource life cycle
There are two ways to load unityengine.objects: automatic loading and display of manual loading. When an instance ID is dereferenced and its corresponding object is not currently loaded into memory, and object's source data can be positioned, the object is automatically loaded. Objects can also display a manual load in the script, such as creating a new texture2d or loading an object by Assetbundle.loadasset mode.
If a file GUID and local ID do not have a corresponding instance ID, or if a instance ID corresponds to an object that is not loaded, and its corresponding GUID and local ID are invalid, then object will not be loaded. However, the reference relationship is still retained, and the "(Missing)" appears in the Unity editor.
Objects will be uninstalled in the following three specific cases:
1. When the unreferenced asset is cleared, unreferenced objects are automatically uninstalled. Cleanup of unreferenced asset is triggered when the scene switches or when the Resources.unloadunusedassets function is called.
2. Objects from the Resources folder is destroyed when the Resources.unloadasset function is called. But the instance ID is retained, so if any previous reference to the object is dereferenced after object is destroyed, unity will re-locate the GUID and local ID through the instance ID, and then load the object again.
3. Objects from Assetbundle is immediately destroyed when the Assetbundle.unload (true) function is called, and the instance id,guid and local IDs become invalid, and any references to that object become "( Missing) ". Any subsequent access to the object in C # throws an "NullReferenceException" exception. If you call Assetbundle.unload (FALSE), the objects loaded from Assetbundle will not be destroyed, but the GUID and local ID corresponding to the instance ID will become invalid, so if these objects are freed from memory, Unity will not be able to load them again.
Loading large-level objects
When serializing Unity Gameobjects (for example, prefabs), keep in mind that the entire hierarchy will be serialized. In other words, each gameobject and its components in the hierarchy are represented independently in the serialized data. Therefore, loading and instantiating large-level gameobjects can have a performance impact.
When instantiating a gameobjects, it takes more CPU time to instantiate a gameobject with a large hierarchy and instantiate several small levels of gameobjects and then combine those gameobjects together. Although instantiating a large-level gameobject does not require a combined gameobjects (no trampolining and sendtransformchanged callbacks) of CPU time, However, these saved CPU time is much more than the time to read and reverse the instantiation of large-level data.
As mentioned earlier, when serializing Gameobjects, Gameobject and its component data in the entire hierarchy are serialized---even if the data is duplicated. For example, if there are 30 buttons in a UI, the button data will be serialized 30 times. At load time, this data needs to be read from disk, and when loading large-level gameobjects, the file read time consumes a lot of CPU time. Therefore, duplicate objects can be removed from the entire hierarchy, then instantiated separately and then grouped into the entire hierarchy.
Unity Learning Note-Assets, Objects and serialization