【问题标题】:Unity sometimes loading a scene twice while using Async loadingUnity 在使用异步加载时有时会加载两次场景
【发布时间】:2020-10-22 01:06:20
【问题描述】:

我有一个“持久场景”,它始终在后台通过 GameManager 脚本处理加载和卸载。激活此脚本的方法是输入触发器并按“E”,这将加载另一个场景。

加载到森林中的示例

触发器上的脚本:

public class ForestEnter : MonoBehaviour
{
    
    void OnTriggerStay2D(Collider2D other)
    {
        
        
        if (Input.GetKey(KeyCode.E))
        {
           GameManager.instance.LoadForest();
        }
    }
}

GameManger 中的部分脚本:

        public void LoadForest()
    {
        scenesLoading.Add(SceneManager.UnloadSceneAsync((int)SceneIndexes.CITY));
        scenesLoading.Add(SceneManager.LoadSceneAsync((int)SceneIndexes.FOREST, LoadSceneMode.Additive));
        spawnname = ("CityExit");
        sceneName = ("Forest");
        StartCoroutine(GetSceneLoadProgress());

    }

以及它正在调用的协程(确保它等到所有内容都加载完毕后再找到生成点并将场景设置为“活动场景”)

    public IEnumerator GetSceneLoadProgress()
    {
        for(int i=0; i<scenesLoading.Count; i++)
        {
            while (!scenesLoading[i].isDone)
            {
                yield return null;
            }
        }
        player = GameObject.Find("PC");
        playerPOS = player.transform;
        spawn = GameObject.Find(spawnname);
        spawnPOS = spawn.transform;
        playerPOS.position = spawnPOS.position;
        SceneManager.SetActiveScene(SceneManager.GetSceneByName(sceneName));
        
    }

现在我的问题是有时它会加载两次场景,因为总共会播放 3 个场景,GameManager 场景、森林场景和森林场景。但它只是偶尔发生,不是每次都发生。

我认为问题在于,如果我按住“E”太久,它会在卸载之前尽可能多地调用脚本,但我不知道如何停止它.

任何帮助或建议将不胜感激!

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    正如@HassanOmar 所说,问题是您多次触发负载。这是因为您正在检查 每一帧 按键被按下,但您真的只想要 第一个 帧按键被按下。你可以使用Input.GetKeyDown()

    public class ForestEnter : MonoBehaviour
    {    
        void OnTriggerStay2D(Collider2D other)
        {        
        
            if (Input.GetKeyDown(KeyCode.E))
            {
                GameManager.instance.LoadForest();
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      这是由于多次调用OnTriggerStay2D,您可以使用布尔变量来避免这种情况

        public class ForestEnter : MonoBehaviour
        {
               public bool flag = true;
          
               void OnTriggerStay2D(Collider2D other)
               {
              
              
                   if (Input.GetKey(KeyCode.E) && flag)
                   { 
                       GameManager.instance.LoadForest();
                       flag  =false; 
                   }
               }
           }
      

      仅在您需要时使用
      您也可以在新场景中的任何脚本的启动函数中重置此标志 或在加载下一个场景的操作结束时重置 这是行之有效的方法

      FindObjectOfType<ForestEnter>().flag = true;
      

      【讨论】:

      • 您对错误的理解是正确的,但您的解决方案...次优。
      • 感谢您抽出宝贵时间提供帮助,但 Immersive 的做法要简单得多。
      • 没关系,我知道 Immersive 的解决方案是最佳的,但如果您不必检查是否按下了 E 键“例如为手机设计了此产品”,您将使用我的解决方案
      • 嗯,不,因为即使在移动设备上,您也可能会使用Input 系统,或者具有自己的触发一次功能的 UI Button。当没有现成的“状态变化”指标可用时,您的答案很好,但用户输入中间件很少出现这种情况。
      猜你喜欢
      • 2022-08-02
      • 2019-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-03
      • 1970-01-01
      相关资源
      最近更新 更多