Unity有时会在使用异步加载时加载场景两次,

时间:2020-10-22 01:06:20

标签: c# unity3d

我有一个“ Persistent Scene”,它始终在后台,通过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场景,Forest场景和Forest场景。但这只是有时发生,而不是每次都发生。

我认为问题在于,如果我按住“ E”的时间太长,它将在卸载脚本之前尽可能多地调用脚本,但是我不知道如何停止该脚本

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

2 个答案:

答案 0 :(得分:1)

正如@HassanOmar所说,问题是您多次触发了加载。这是因为您要检查每帧键被按下,但是您实际上只希望按下键的第一帧。您可以使用Input.GetKeyDown()进行此操作:

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

答案 1 :(得分:0)

由于多次调用 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;