You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity:缓存下载后的SceneInstance无法激活的技术问题

问题分析与解决

核心问题

你的缓存逻辑仅跟踪了场景是否加载过,未处理场景被卸载或场景已处于激活状态的情况:

  • 当用LoadSceneMode.Single加载其他场景时,主菜单场景会被自动卸载,但_isLoaded标记仍为true,返回的_cachedScene已失效
  • 若主菜单场景已经激活,调用ActivateAsync不会触发任何操作,因为场景本身就是激活状态

修复方案

方案1:添加缓存有效性检查

修改MainMenuProvider,在返回缓存前验证场景是否仍有效:

class MainMenuProvider
{
    private static SceneInstance _cachedScene;
    private static bool _isLoaded;

    public async Task<SceneInstance> Load()
    {
        // 检查缓存场景是否已失效(未加载或无效)
        if (_isLoaded && (!_cachedScene.Scene.IsValid() || !_cachedScene.Scene.isLoaded))
        {
            _isLoaded = false;
        }

        if (!_isLoaded)
        {
            var mainMenuLoadHandle =
                Addressables.LoadSceneAsync("Assets/Bundles/UI/Scenes/MainMenu.unity", LoadSceneMode.Single, false);
            await mainMenuLoadHandle.Task;
            _cachedScene = mainMenuLoadHandle.Result;
            _isLoaded = true;
        }

        return _cachedScene;
    }
}

方案2:激活前检查场景状态

调用ActivateAsync前先判断场景是否未激活,避免无效调用:

var sceneInstance = await mainMenuProvider.Load();
if (!sceneInstance.Scene.isActive)
{
    await sceneInstance.ActivateAsync();
}

方案3:实例化管理+场景卸载监听

静态缓存易导致状态不一致,改为实例化类并监听场景卸载事件:

class MainMenuProvider
{
    private SceneInstance? _cachedScene;
    private bool _isLoaded;

    public MainMenuProvider()
    {
        SceneManager.sceneUnloaded += OnSceneUnloaded;
    }

    private void OnSceneUnloaded(Scene scene)
    {
        if (_cachedScene.HasValue && _cachedScene.Value.Scene == scene)
        {
            _cachedScene = null;
            _isLoaded = false;
        }
    }

    public async Task<SceneInstance> Load()
    {
        if (!_isLoaded || !_cachedScene.HasValue || !_cachedScene.Value.Scene.IsValid())
        {
            var mainMenuLoadHandle =
                Addressables.LoadSceneAsync("Assets/Bundles/UI/Scenes/MainMenu.unity", LoadSceneMode.Single, false);
            await mainMenuLoadHandle.Task;
            _cachedScene = mainMenuLoadHandle.Result;
            _isLoaded = true;
        }

        return _cachedScene.Value;
    }
}

额外注意事项

  • 用SceneInstance.Scene.IsValid()和Scene.isLoaded可准确判断场景实际状态
  • 若需频繁切换场景,建议用LoadSceneMode.Additive加载主菜单,避免被Single模式卸载,同时手动管理激活状态

内容的提问来源于stack exchange,提问作者Виктор Титов

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 21:31:06