Unity3D游戏在启动时都默认加载哪些资源

我们都知道使用Unity3D引擎制作的游戏在冷启动时会加载一些默认的资源,包括纹理资源、Shader、Mesh等,这些资源都是Unity3D引擎默认需要的。

那么我们如何知道这些默认资源到底是哪些呢?为了深入理解这个主题,我们把这个问题分解成以下两个子问题:

1.Unity3D引擎会包含哪些默认资源?

2.Unity3D引擎在从冷启动到开始加载第一个场景(Scene)时,需要加载哪些资源呢?

第一个问题也就是游戏的包体中会包含哪些非用户添加的资源,这些资源是Unity3D引擎自动添加的资源,最终也会打包进游戏里面,占用包体大小。

第二个问题是游戏在运行时,从用户点击游戏开始冷启动,到显示启动屏(Splash

Screen),直到开始加载第一个游戏场景前,Unity3D引擎需要把哪些资源加载到内存中?我们称之为冷启动时需要加载哪些资源,这些冷启动需要加载的资源直接影响游戏的冷启动时间。

Unity3D引擎会包含哪些默认资源

分析这个问题,我们可以用Unity3D创建一个新的空工程,只有一个场景,场景上不挂在任何GameObject(把默认添加的MainCamera等删除掉)。这样的空工程可以保证工程里面没有任何用户引入的资源,保证工程的干净,方便我们分析。然后,我们可以导出一个Android的APK包。

这个APK包已经是Unity3D引擎最小的包体大小了,我们可以看到这个包体仍然有21.5MB之大,而我们使用AndroidStudio创建一个空的工程,导出的APK只有1.8MB,相比而言,Unity3D的包体还是蛮大的。

APK就是一个zip压缩包,把后缀.apk替换为.zip,就可以把APK包解压出来,从包体里面我们就可以看到有哪些资源了。如果你使用Mac,那么你可以使用tree命令来得到如下的图示:

我们可以看到assets/bin/Data/目录下面有Unity3D引擎的.dll文件,以及lib/目录下的.so文件,这些都是Unity3D引擎的代码文件,剩下的那些就是Unity3D引擎引入的资源文件。

我们重点关注上图中划红线的unity_builtin_extraunity default resources这两个文件,它们在文件大小上是资源文件中最大的。

从文件名的命名上我们可以猜想这些应该就是Unity3D引擎引入的默认资源,那么我们怎么才能看到这些资源到底是什么呢?由于这些文件是类似于AssetBundle的文件格式,所以我们需要首先把这两个文件进行拆包,然后才可以看到其内部结构。

我使用的DevXUnityUnPack这个工具进行拆包操作,这个工具很强大,可以直接对APK文件进行拆包。

我们重点关注unity_builtin_extraunity default resources这两个文件里面有哪些资源:

你会看到unity_builtin_extra里面都是Shader文件,而unity default resources里面则包含纹理、默认的Arial字体、材质、Shader等。

Unity3D引擎冷启动时需要加载哪些资源

我们如何分析哪些资源被加载了呢?我们可以使用Resources.FindObjectsOfTypeAll方法来列出来哪些文件被加载了,它会把内部的对象以及被Disable的对象也列出来。

我们在场景上新建一个obj1GameObject,并挂在Test.cs脚本,Test.cs代码如下:

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using System.IO;

using System;

public class Test : MonoBehaviour

{

void Start ()

{

string str = "";

var objs = Resources.FindObjectsOfTypeAll();

str= "total objs length = "objs.Length"\n";

foreach(var obj in objs)

{

Type type = obj.GetType();

str= "name = "obj.name", type = "type;

str= "\n";

}

string path = Path.Combine(Application.persistentDataPath, "logs.txt");

File.WriteAllText(path, str);

}

}

游戏场景结构如下所示:

我们在Android手机上运行游戏(注意:一定要在真机上运行,在Editor里面运行得到的信息是不准确的,会把Unity3D Editor加载的资源也列出来),可以得到下面的logs.txt信息:

total objs length = 216

name = NavMeshSettings, type = UnityEngine.Object

name = OcclusionCullingSettings, type = UnityEngine.Object

name = , type = UnityEngine.Material

name = UnityNHxRoughness, type = UnityEngine.Texture2D

name = UnityDitherMask3D, type = UnityEngine.Texture3D

name = UnityDitherMask2D, type = UnityEngine.Texture2D

name = UnityDefaultCube, type = UnityEngine.Cubemap

name = UnityDefault2DArray, type = UnityEngine.Texture2DArray

name = UnityDefault3D, type = UnityEngine.Texture3D

name = UnityDefault2D, type = UnityEngine.Texture2D

name = UnityBlackCube, type = UnityEngine.Cubemap

name = UnityAttenuation, type = UnityEngine.Texture2D

name = UnityHalo, type = UnityEngine.Texture2D

name = UnityGrayscaleRamp, type = UnityEngine.Texture2D

name = UnityGrey, type = UnityEngine.Texture2D

name = UnityRed, type = UnityEngine.Texture2D

name = UnityRandomRotation, type = UnityEngine.Texture2D

name = UnityBlack, type = UnityEngine.Texture2D

name = UnityWhite, type = UnityEngine.Texture2D

name = UnityNormalMap, type = UnityEngine.Texture2D

name = InternalIdentityTransform, type = UnityEngine.Transform

name = InternalIdentityTransform, type = UnityEngine.GameObject

name = PlayerSettings, type = UnityEngine.Object

name = InputManager, type = UnityEngine.Object

name = BuildSettings, type = UnityEngine.Object

name = GraphicsSettings, type = UnityEngine.Rendering.GraphicsSettings

name = Hidden/Internal-DeferredShading, type = UnityEngine.Shader

name = Hidden/Internal-DeferredReflections, type = UnityEngine.Shader

name = Hidden/Internal-ScreenSpaceShadows, type = UnityEngine.Shader

name = Hidden/Internal-PrePassLighting, type = UnityEngine.Shader

name = Hidden/Internal-DepthNormalsTexture, type = UnityEngine.Shader

name = Hidden/Internal-MotionVectors, type = UnityEngine.Shader

name = Hidden/Internal-Halo, type = UnityEngine.Shader

name = Hidden/Internal-Flare, type = UnityEngine.Shader

name = Legacy Shaders/Diffuse, type = UnityEngine.Shader

name = Hidden/CubeBlur, type = UnityEngine.Shader

name = Hidden/CubeCopy, type = UnityEngine.Shader

name = Hidden/CubeBlend, type = UnityEngine.Shader

name = Sprites/Default, type = UnityEngine.Shader

name = UI/Default, type = UnityEngine.Shader

name = Hidden/VideoDecode, type = UnityEngine.Shader

name = Hidden/VideoDecodeAndroid, type = UnityEngine.Shader

name = Hidden/Internal-StencilWrite, type = UnityEngine.Shader

name = Hidden/Internal-CombineDepthNormals, type = UnityEngine.Shader

name = Hidden/BlitCopy, type = UnityEngine.Shader

name = Hidden/BlitCopyDepth, type = UnityEngine.Shader

name = Hidden/Internal-GUITextureClip, type = UnityEngine.Shader

name = Hidden/Internal-GUITextureClipText, type = UnityEngine.Shader

name = Hidden/Internal-GUITexture, type = UnityEngine.Shader

name = Hidden/Internal-GUITextureBlit, type = UnityEngine.Shader

name = Hidden/ConvertTexture, type = UnityEngine.Shader

name = Hidden/VR/BlitCopyFromTexArray, type = UnityEngine.Shader

name = Sprites-Default, type = UnityEngine.Material

name = QualitySettings, type = UnityEngine.QualitySettings

name = RuntimeInitializeOnLoadManager, type = UnityEngine.Object

name = Hidden/InternalErrorShader, type = UnityEngine.Shader

name = Soft, type = UnityEngine.Texture2D

name = DeveloperConsole, type = UnityEngine.TextAsset

name = GUISkin, type = UnityEngine.TextAsset

name = TagManager, type = UnityEngine.Object

name = AudioManager, type = UnityEngine.Object

name = ScriptMapper, type = UnityEngine.Object

name = Legacy Shaders/VertexLit, type = UnityEngine.Shader

name = Skybox/Procedural, type = UnityEngine.Shader

name = MonoManager, type = UnityEngine.Object

name = AudioSpatializerMicrosoft, type = UnityEngine.TextAsset

name = SpatialMappingBase, type = UnityEngine.TextAsset

name = SpatialMappingCollider, type = UnityEngine.TextAsset

name = SpatialMappingRenderer, type = UnityEngine.TextAsset

name = HoloLensInput, type = UnityEngine.TextAsset

name = HoloLensInputModule, type = UnityEngine.TextAsset

name = PlaymodeTestsController, type = UnityEngine.TextAsset

name = PlayModeRunnerCallback, type = UnityEngine.TextAsset

name = CallbackExecutor, type = UnityEngine.TextAsset

name = Placeholder, type = UnityEngine.TextAsset

name = AnalyticsTracker, type = UnityEngine.TextAsset

name = NetworkAnimator, type = UnityEngine.TextAsset

name = NetworkBehaviour, type = UnityEngine.TextAsset

name = NetworkDiscovery, type = UnityEngine.TextAsset

name = NetworkIdentity, type = UnityEngine.TextAsset

name = NetworkLobbyManager, type = UnityEngine.TextAsset

name = NetworkLobbyPlayer, type = UnityEngine.TextAsset

name = NetworkManager, type = UnityEngine.TextAsset

name = NetworkManagerHUD, type = UnityEngine.TextAsset

name = NetworkMigrationManager, type = UnityEngine.TextAsset

name = NetworkProximityChecker, type = UnityEngine.TextAsset

name = NetworkStartPosition, type = UnityEngine.TextAsset

name = NetworkTransformChild, type = UnityEngine.TextAsset

name = NetworkTransform, type = UnityEngine.TextAsset

name = NetworkTransformVisualizer, type = UnityEngine.TextAsset

name = AsyncUtil, type = UnityEngine.TextAsset

name = NetworkAnimator, type = UnityEngine.TextAsset

name = NetworkBehaviour, type = UnityEngine.TextAsset

name = NetworkDiscovery, type = UnityEngine.TextAsset

name = NetworkIdentity, type = UnityEngine.TextAsset

name = NetworkLobbyManager, type = UnityEngine.TextAsset

name = NetworkLobbyPlayer, type = UnityEngine.TextAsset

name = NetworkManager, type = UnityEngine.TextAsset

name = NetworkManagerHUD, type = UnityEngine.TextAsset

name = NetworkMigrationManager, type = UnityEngine.TextAsset

name = NetworkProximityChecker, type = UnityEngine.TextAsset

name = NetworkStartPosition, type = UnityEngine.TextAsset

name = NetworkTransformChild, type = UnityEngine.TextAsset

name = NetworkTransform, type = UnityEngine.TextAsset

name = NetworkTransformVisualizer, type = UnityEngine.TextAsset

name = EventSystem, type = UnityEngine.TextAsset

name = EventTrigger, type = UnityEngine.TextAsset

name = UIBehaviour, type = UnityEngine.TextAsset

name = BaseInput, type = UnityEngine.TextAsset

name = BaseInputModule, type = UnityEngine.TextAsset

name = PointerInputModule, type = UnityEngine.TextAsset

name = StandaloneInputModule, type = UnityEngine.TextAsset

name = TouchInputModule, type = UnityEngine.TextAsset

name = BaseRaycaster, type = UnityEngine.TextAsset

name = Physics2DRaycaster, type = UnityEngine.TextAsset

name = PhysicsRaycaster, type = UnityEngine.TextAsset

name = Button, type = UnityEngine.TextAsset

name = Dropdown, type = UnityEngine.TextAsset

name = Graphic, type = UnityEngine.TextAsset

name = GraphicRaycaster, type = UnityEngine.TextAsset

name = Image, type = UnityEngine.TextAsset

name = InputField, type = UnityEngine.TextAsset

name = Mask, type = UnityEngine.TextAsset

name = MaskableGraphic, type = UnityEngine.TextAsset

name = RawImage, type = UnityEngine.TextAsset

name = RectMask2D, type = UnityEngine.TextAsset

name = Scrollbar, type = UnityEngine.TextAsset

name = ScrollRect, type = UnityEngine.TextAsset

name = Selectable, type = UnityEngine.TextAsset

name = Slider, type = UnityEngine.TextAsset

name = Text, type = UnityEngine.TextAsset

name = Toggle, type = UnityEngine.TextAsset

name = ToggleGroup, type = UnityEngine.TextAsset

name = AspectRatioFitter, type = UnityEngine.TextAsset

name = CanvasScaler, type = UnityEngine.TextAsset

name = ContentSizeFitter, type = UnityEngine.TextAsset

name = GridLayoutGroup, type = UnityEngine.TextAsset

name = HorizontalLayoutGroup, type = UnityEngine.TextAsset

name = HorizontalOrVerticalLayoutGroup, type = UnityEngine.TextAsset

name = LayoutElement, type = UnityEngine.TextAsset

name = LayoutGroup, type = UnityEngine.TextAsset

name = VerticalLayoutGroup, type = UnityEngine.TextAsset

name = BaseMeshEffect, type = UnityEngine.TextAsset

name = Outline, type = UnityEngine.TextAsset

name = PositionAsUV1, type = UnityEngine.TextAsset

name = Shadow, type = UnityEngine.TextAsset

name = EventSystem, type = UnityEngine.TextAsset

name = EventTrigger, type = UnityEngine.TextAsset

name = UIBehaviour, type = UnityEngine.TextAsset

name = BaseInput, type = UnityEngine.TextAsset

name = BaseInputModule, type = UnityEngine.TextAsset

name = PointerInputModule, type = UnityEngine.TextAsset

name = StandaloneInputModule, type = UnityEngine.TextAsset

name = TouchInputModule, type = UnityEngine.TextAsset

name = BaseRaycaster, type = UnityEngine.TextAsset

name = Physics2DRaycaster, type = UnityEngine.TextAsset

name = PhysicsRaycaster, type = UnityEngine.TextAsset

name = Button, type = UnityEngine.TextAsset

name = Dropdown, type = UnityEngine.TextAsset

name = Graphic, type = UnityEngine.TextAsset

name = GraphicRaycaster, type = UnityEngine.TextAsset

name = Image, type = UnityEngine.TextAsset

name = InputField, type = UnityEngine.TextAsset

name = Mask, type = UnityEngine.TextAsset

name = MaskableGraphic, type = UnityEngine.TextAsset

name = RawImage, type = UnityEngine.TextAsset

name = RectMask2D, type = UnityEngine.TextAsset

name = Scrollbar, type = UnityEngine.TextAsset

name = ScrollRect, type = UnityEngine.TextAsset

name = Selectable, type = UnityEngine.TextAsset

name = Slider, type = UnityEngine.TextAsset

name = Text, type = UnityEngine.TextAsset

name = Toggle, type = UnityEngine.TextAsset

name = ToggleGroup, type = UnityEngine.TextAsset

name = AspectRatioFitter, type = UnityEngine.TextAsset

name = CanvasScaler, type = UnityEngine.TextAsset

name = ContentSizeFitter, type = UnityEngine.TextAsset

name = GridLayoutGroup, type = UnityEngine.TextAsset

name = HorizontalLayoutGroup, type = UnityEngine.TextAsset

name = HorizontalOrVerticalLayoutGroup, type = UnityEngine.TextAsset

name = LayoutElement, type = UnityEngine.TextAsset

name = LayoutGroup, type = UnityEngine.TextAsset

name = VerticalLayoutGroup, type = UnityEngine.TextAsset

name = BaseMeshEffect, type = UnityEngine.TextAsset

name = Outline, type = UnityEngine.TextAsset

name = PositionAsUV1, type = UnityEngine.TextAsset

name = Shadow, type = UnityEngine.TextAsset

name = AudioSpatializerMicrosoft, type = UnityEngine.TextAsset

name = SpatialMappingBase, type = UnityEngine.TextAsset

name = SpatialMappingCollider, type = UnityEngine.TextAsset

name = SpatialMappingRenderer, type = UnityEngine.TextAsset

name = HoloLensInput, type = UnityEngine.TextAsset

name = HoloLensInputModule, type = UnityEngine.TextAsset

name = Test, type = UnityEngine.TextAsset

name = TimeManager, type = UnityEngine.Object

name = DelayedCallManager, type = UnityEngine.Object

name = PhysicsManager, type = UnityEngine.Object

name = ResourceManager, type = UnityEngine.Object

name = NetworkManager, type = UnityEngine.Object

name = MasterServerInterface, type = UnityEngine.Object

name = NavMeshProjectSettings, type = UnityEngine.Object

name = Physics2DSettings, type = UnityEngine.Object

name = CloudWebServicesManager, type = UnityEngine.Object

name = UnityAnalyticsManager, type = UnityEngine.Object

name = UnityConnectSettings, type = UnityEngine.Object

name = PerformanceReportingManager, type = UnityEngine.Object

name = , type = UnityEngine.Object

name = , type = UnityEngine.Object

name = Default-Skybox, type = UnityEngine.Material

name = , type = UnityEngine.Cubemap

name = , type = UnityEngine.LightProbes

name = obj1, type = UnityEngine.GameObject

name = obj1, type = UnityEngine.Transform

name = RenderSettings, type = UnityEngine.RenderSettings

name = LightmapSettings, type = UnityEngine.LightmapSettings

name = obj1, type = Test

我们会发现这么简单的一个场景,在冷启动时,足足需要加载216个对象!是不是有点吃惊呢。这些对象有Shader、Texture2D、TextAsset等,比如GraphicsSettings、UnityNormalMap、Sprites/Default等, 很大一部分都是Unity3D引擎默认需要的。我们重点来关注我们自己引入的对象:

name = Test, type = UnityEngine.TextAsset

...

...

name = obj1, type = UnityEngine.GameObject

name = obj1, type = UnityEngine.Transform

name = RenderSettings, type = UnityEngine.RenderSettings

name = LightmapSettings, type = UnityEngine.LightmapSettings

name = obj1, type = Test

Test.cs代码本身就是一个TextAsset,需要在启动时进行加载。obj1是场景里面的GameObject的名字,它所挂载的Transform组件也需要被加载。

即使代码脚本没有被使用,它也会在冷启动时加载,所以,如果一个大型项目里面有很多的代码文件,那么这些代码文件都需要被加载,这将会影响游戏的冷启动时间。所以,如果有很多的代码文件,可以考虑把这些代码文件打包成一个.dll文件,这样可以减少碎片化文件的加载时间,从而减少冷启动时间,加快游戏启动速度。

你可能感兴趣的:(Unity3D游戏在启动时都默认加载哪些资源)