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

Unity协程调用房间重置函数后敌人Spawn异常问题求助

Unity房间重置函数Spawn异常问题

我在Unity开发中遇到一个Bug:编写的房间重置函数Spawnear()负责清除旧网格、生成网格向量列表、随机Spawn物体(彼此间隔至少一格)和敌人。当通过碰撞触发协程调用该函数时,若在yield return后调用,物体Spawn正常,但敌人仅在特定区域生成;若在yield return前调用则完全正常。已确认敌人网格数据无问题,需要实现先执行过渡动画再重置房间,同时解决该异常。

效果对比

  • 正常效果:函数直接调用或协程yield return前调用时,敌人在全网格随机生成
  • 异常效果:协程yield return后调用时,敌人仅在特定区域生成

相关代码

1. 碰撞触发物体脚本

private void OnTriggerEnter2D(Collider2D collision)
{
    if (collision.tag == "Player")
    {
        StartCoroutine(Siguiente());
    }
}

private IEnumerator Siguiente()
{
    Color newColor = Color.clear;
    while (BlackScreen.GetComponent<Image>().color.a < 1)
    {
        newColor.a += 0.01f;
        BlackScreen.GetComponent<Image>().color = newColor;
        yield return null;
    }

    scrRoomSpawner roomSpawnerScript = roomSpawner.GetComponent<scrRoomSpawner>();
 
    foreach (GameObject instancia in roomSpawnerScript.instancias)
    {
        Destroy(instancia);
    }

    roomSpawnerScript.Spawnear();
    player.transform.position = playerSpawnPos;

    yield return new WaitForSeconds(1);

    while (BlackScreen.GetComponent<Image>().color.a > 0)
    {
        newColor.a -= 0.01f;
        BlackScreen.GetComponent<Image>().color = newColor;
        yield return null;
    }
}

2. 房间重置物体(RoomSpawner)脚本

public class scrRoomSpawner : MonoBehaviour
{
    public float gridWidth;
    public float gridHeight;
    public float objectNumber;
    public float enemyNumber;

    public GameObject bloque;
    public GameObject enemy;
    public GameObject enviroment;
    public GameObject aa;
    private List<Vector2> gridObjetos = new List<Vector2>();
    private List<Vector2> gridEnemigos = new List<Vector2>();
    public List<GameObject> instancias = new List<GameObject>();

    void Start()
    {
        Spawnear();
    }

    void Update()
    {
    }

    public void Spawnear()
    {
        gridObjetos.Clear();
        gridEnemigos.Clear();

        for (int x = 0; x < gridWidth; x++)
        {
            for (int y = 0; y < gridHeight; y++)
            {
                gridObjetos.Add(new Vector2(x - 7.5f, y - 5.5f));
            }
        }

        for (int x = 0; x < gridWidth; x++)
        {
            for (int y = 0; y < gridHeight; y++)
            {
                gridEnemigos.Add(new Vector2(x - 7.5f, y - 5.5f));
            }
        }

        for (int i = 0; i < objectNumber; i++)
        {
            if (gridObjetos.Count > 0)
            {
                GameObject objeto = Instantiate(bloque);
                objeto.transform.SetParent(enviroment.transform);
                instancias.Add(objeto);
                objeto.transform.position = gridObjetos[Random.Range(0, gridObjetos.Count)];
                Vector2 vectorObjeto = objeto.transform.position;

                Vector2 minBound = vectorObjeto - new Vector2(1, 1);
                Vector2 maxBound = vectorObjeto + new Vector2(1, 1);

                gridObjetos.RemoveAll(v => v.x >= minBound.x && v.x <= maxBound.x && v.y >= minBound.y && v.y <= maxBound.y);
            }
        }

        for (int i = 0; i < enemyNumber; i++)
        {
            GameObject enemigo = Instantiate(enemy);
            instancias.Add(enemigo);
            enemigo.transform.position = gridEnemigos[Random.Range(0, gridEnemigos.Count)];
            Vector2 vectorEnemigo = enemigo.transform.position;

            gridEnemigos.Remove(vectorEnemigo);
        }
    }
}

已尝试方案

曾将Spawnear()调用放在协程的yield return前,问题解决,但无法满足先执行过渡动画再重置房间的需求。

内容的提问来源于stack exchange,提问作者MarcosT

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 12:34:51