首页 > 解决方案 > 将所有内容打包到资源中仍然会影响场景加载时间吗?

问题描述

我在低端设备上的加载时间遇到了严重问题。我的一位测试人员报告说,启动游戏最多需要一分钟,而其他任何游戏都不需要这么长时间。

我决定通过将每个资产放入 Resources 并制作 LoadingScreen 场景来“解决”这个问题。它几乎完全是空的——一个文本字段和 16 个图像表示在特定时刻加载的部分,以及一个名为 LoadingScreen.cs 的脚本,它将所有内容预加载到内存中。这里是:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using TMPro;

public class LoadingScreen : MonoBehaviour {
    public GameObject[] steps;
    public GameObject text;
    public GameObject theCamera;
    public GameObject loaderObjects;

    Object[] textures;
    Object[] sprites;
    Object[] models;
    Object[] materials;
    Object[] audios;
    Object[] animations;
    Object[] shaders;
    Object[] fonts;
    Object[] scripts;

    void Start() {
        Physics.autoSimulation = false;

        StartCoroutine (Initialization ());
    }

    IEnumerator Initialization() {

        text.GetComponent<TMP_Text> ().text = "INITIALIZATION";

        GameObject MainCameraPrefab = Resources.Load("Prefabs/Main Camera") as GameObject;
        theCamera = Instantiate (MainCameraPrefab, Vector3.zero, Quaternion.Euler (Vector3.zero));

        yield return new WaitForSeconds(0.1f);
        StartCoroutine (LoadScenes ());
    }

    IEnumerator LoadScenes() {
        steps[0].gameObject.SetActive(true);

        text.GetComponent<TMP_Text> ().text = "LOADING SCENES";

        theCamera.GetComponent<LevelChanger> ().StartLoadingLevels ();

        yield return new WaitForSeconds(0.1f);
        StartCoroutine (LoadTextures ());
    }

    IEnumerator LoadTextures() {
        steps[1].gameObject.SetActive(true);

        text.GetComponent<TMP_Text> ().text = "LOADING TEXTURES & SPRITES";

        textures = Resources.LoadAll("Models/Textures", typeof(Texture2D));
        sprites = Resources.LoadAll("Sprites", typeof(Texture2D));

        yield return new WaitForSeconds(0.1f);
        StartCoroutine (LoadMeshes ());
    }

    IEnumerator LoadMeshes() {
        steps[2].gameObject.SetActive(true);

        text.GetComponent<TMP_Text> ().text = "LOADING MESHES & MATERIALS";

        materials = Resources.LoadAll("Models/Materials", typeof(Material));
        models = Resources.LoadAll("Models", typeof(Mesh));

        yield return new WaitForSeconds(0.1f);
        StartCoroutine (LoadAudio ());
    }

    IEnumerator LoadAudio() {
        steps[3].gameObject.SetActive(true);

        text.GetComponent<TMP_Text> ().text = "LOADING AUDIO";

        audios = Resources.LoadAll("Sounds", typeof(AudioClip));

        yield return new WaitForSeconds(0.1f);
        StartCoroutine (LoadAssets ());
    }

    IEnumerator LoadAssets() {
        steps[4].gameObject.SetActive(true);

        text.GetComponent<TMP_Text> ().text = "LOADING OTHER ASSETS";

        animations = Resources.LoadAll("Animations");
        shaders = Resources.LoadAll("Shaders");
        fonts = Resources.LoadAll("Fonts");

        yield return new WaitForSeconds(0.1f);
        StartCoroutine (LoadScripts ());
    }

    IEnumerator LoadScripts() {
        steps[5].gameObject.SetActive(true);

        text.GetComponent<TMP_Text> ().text = "LOADING SCRIPTS";

        scripts = Resources.LoadAll("Scripts");

        yield return new WaitForSeconds(0.1f);
        StartCoroutine (InitializeScripts ());
    }

    IEnumerator InitializeScripts() {
        steps[6].gameObject.SetActive(true);

        text.GetComponent<TMP_Text> ().text = "INITIALIZING SCRIPTS";

        theCamera.GetComponent<SaveGame> ().enabled = true;
        theCamera.GetComponent<SteamManager> ().enabled = true;
        theCamera.GetComponent<CameraControl> ().enabled = true;
        theCamera.GetComponent<FPSCounter> ().enabled = true;
        theCamera.GetComponent<TimerCounter> ().enabled = true;
        theCamera.GetComponent<TimeManager> ().enabled = true;
        theCamera.GetComponent<BlurControl> ().enabled = true;
        theCamera.GetComponent<Pause> ().enabled = true;
        theCamera.GetComponent<SkyboxRotation> ().enabled = true;
        theCamera.GetComponent<SoundManager> ().enabled = true;

        yield return new WaitForSeconds(0.1f);
        StartCoroutine (Done ());
    }

    IEnumerator Done() {
        steps[7].gameObject.SetActive(true);

        text.GetComponent<TMP_Text> ().text = "DONE";

        yield return new WaitForSeconds(0.4f);

        theCamera.GetComponent<LevelChanger> ().ActivateMenu ();
        Destroy (loaderObjects);
    }
}

场景是这样的:

在此处输入图像描述

好吧,我知道这不是一种常见的方法,但它特别适合我,因为大多数关卡只是重复使用相同的预制件、相同的模型和相同的材料。预加载所有内容只需要额外使用数百兆字节的内存,但它会大大加快场景加载时间!

嗯,它确实加快了不同场景的加载速度,并且在第一次放置一些预制件时消除了第一次打嗝。好的。但它对我的初始加载时间没有帮助,根本没有,仍然需要很多时间来启动游戏。我检查了场景的依赖关系:

在此处输入图像描述

一个精灵 - 圆圈的那一部分,一些与 TextMeshPro 相关的资产,一个着色器和两个脚本 - 我上面提到的一个和一个防止我的预加载对象在更改场景时被破坏的一个(这只是一行,也不重要)。

我之前读过资源在我决定使用它们之前不会加载到内存中。那么这里的问题可能是什么?为什么 Unity 需要这么长时间才能启动一个空场景?

标签: c#unity3d

解决方案


推荐阅读