Uniyt : 场景LoadLevel时资源和对象的处理流程

准备工作

之前对于场景切换没有明确的做个测试,只是避开场景与场景之间的资源关联。现在需要去做资源管理,顺便就来测试下。
每个场景里面都放一个GameObject用来打印Log,我们通过Log的顺序来知道执行的顺序,然后再通过查看Profiler来查看当前内存加载的资源情况。

脚本

ChangeScene .cs 用来控制切换场景

public class ChangeScene : MonoBehaviour {
    public string sceneName;
    AsyncOperation asyncOperation;
    void OnGUI()
    {
        sceneName = GUILayout.TextField(sceneName);
        if (GUILayout.Button("Change"))
        {
            asyncOperation = Application.LoadLevelAsync(sceneName);
            asyncOperation.allowSceneActivation = false;
            Debug.Log("allowSceneActivation : " + asyncOperation.allowSceneActivation);
        }
        if (GUILayout.Button("SceneActivatio") && asyncOperation != null)
        {
            asyncOperation.allowSceneActivation = true;
            Debug.Log("allowSceneActivation : " + asyncOperation.allowSceneActivation);
        }
    }
}

CTest.cs

using UnityEngine;
using System.Collections;

public class CTest : MonoBehaviour {

    void Awake()
    {
        Debug.Log("Awake : " + gameObject.name);
    }
    void Start()
    {
        Debug.Log("Start : " + gameObject.name);
    }
    void OnEnable()
    {
        Debug.Log("OnEnable : " + gameObject.name);
    }
    void OnLevelWasLoaded()
    {
        Debug.Log("OnLevelWasLoaded : " + gameObject.name);
    }

    void OnDestroy()
    {
        Debug.Log("OnDestroy : " + gameObject.name);
    }
}

场景对象

我们创建3个场景 A B C
A:只放两个GameObject分别挂上脚本ChangeScene和CTest
这里写图片描述

B: 放入一个Cube并引用一张贴图,再放入一个GameObject挂上脚本CTest
这里写图片描述

C:一个空场景什么都不放

开始测试

先运行A场景,打印情况如下。 同时也能知道,当前并没有加载我们测试的那张贴图”long”

然后我们输入B,点击Change。也就是调用

asyncOperation = Application.LoadLevelAsync("B");
asyncOperation.allowSceneActivation = false;

当allowSceneActivation为false时,只会将场景加载进去,当他的值为true的时候,才会执行切换操作

这里写图片描述
看图发现已经将贴图加载进内存了,但是场景里面并没有发生任何变化。

我们将allowSceneActivation设置为true,场景就切换到B了。这是日志打印情况
这里写图片描述
至此,我们就知道场景切换的顺序流程了

但是还有一点,需要确认场景切换,资源释放的问题,于是我们继续将场景切换到C,也就是没有任何资源的Scene。
当我切换到C以后,去查看Profiler,发现资源已经释放了。

想到Unity管理资源如果有引用则不释放的思路,去做了一个测试。我写了一个脚本,把B里面的材质保存起来,再从B切换到C。当然这个脚本对象也做了DontDestroyOnLoad,不会被销毁。
运行测试,果然是这样,可以看到资源并没有被释放。
这里写图片描述

结论

  • 首先执行LoadLevelAsync的时候,先加载引用的全部资源

    • 当allowSceneActivation为true后,开始执行切换场景
    • 删除当前场景的所有对象,触发当前场景的OnDestroy
    • 创建新场景里的所有对象,触发Awake OnEnable
    • 触发OnLevelWasLoaded
    • 剩下的就是正常流程触发场景对象的Start然后就是Update了
  • 场景引用的的资源会在切换的时候尝试从内存卸载销毁,如果没有被其他地方引用,则会直接从内存卸载销毁,反之则不会被销毁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值