如何使用协程在指定的几秒钟内销毁并生成不同的GameObject?

时间:2019-05-29 22:34:13

标签: c# unity3d

我正在从事儿童教育游戏。教材应与相关的音频文件一起水平滚动。例如,如果在屏幕上显示猫的图像,则猫的声音会播放。

我正在尝试使用协程。但是GameObjects并没有被单独销毁。所有先前产生的GameObject都在等待新产生的GameObject,并且在所有GameObject产生之后立即销毁它们。

[SerializeField] private GameObject[] sceneObjects;
[SerializeField] private int objectSlideSpeed;
[SerializeField] private int timer;
[SerializeField] private float targetLocation;

void Update()
{
    StartCoroutine(SlideLeft());
}

IEnumerator SlideLeft()
{
    for (int i = 0; i < sceneObjects.Length; i++)
    {
        while(sceneObjects[i].transform.position.x > targetLocation)
        {
            sceneObjects[i].transform.Translate(objectSlideSpeed * Time.deltaTime * Vector3.left);
            yield return new WaitForSeconds(timer);

            if (sceneObjects[i].transform.position.x < targetLocation)
            {
                StopSlide(); // objectSlideSpeed = 0;
                Destroy(sceneObjects[i]);
            }
        }
    }
}

预期

  • 应该在int timer中指定的每秒生成不同的GameObject。
  • 每个GameObjects必须达到目标变换位置。
  • 在此位置,GameObject必须等待而没有任何速度,然后播放相关的声音。 (Audio.Play()函数将在稍后的StopSlide()函数中实现)

  • 在播放声音之后,必须销毁GameObject,并应产生另一个。

  • 在不破坏以前的GameObject的情况下,不得产生新的GameObject。
  • 销毁和生成方法不需要任何用户操作。它们会根据timer变量自动发生。

现状

  • 生成第一个GameObject,它到达float targetLocation变量中指定的目标变换位置。
  • 此时,第一个GameObject等待指定的秒数而没有任何速度。
  • 同时,生成新的和不同的GameObject,并且在到达目标位置后,所有生成的GameObject都将全部销毁。

preview

1 个答案:

答案 0 :(得分:0)

[SerializeField] private GameObject[] sceneObjects;
[SerializeField] private int objectSlideSpeed;
[SerializeField] private int timer;
[SerializeField] private float targetLocation;

// When the scene loads, you dont want update or else the coroutine will be called every frame
void Start()
{
    StartCoroutine(SlideLeft());
}

IEnumerator SlideLeft()
{
    for (int i = 0; i < sceneObjects.Length; i++)
    {
        // [Here], on while we check the conidtion and if it is not true we dont step into it
        while(sceneObjects[i].transform.position.x > targetLocation)
        {
            sceneObjects[i].transform.Translate(objectSlideSpeed * Time.deltaTime * Vector3.left);
            // Why you need a timer, if your goal is to start a gameobject when the other one arrived,
            // at its destination? O.o
            // yield return new WaitForSeconds(timer);

            yield return null; // After this yield execution will continue on the [Here] Tag
        }
        StopSlide();
        Destroy(sceneObjects[i]);
    }
}

在您的预期行为中,有些事情我不理解,但是如果我误解了一些内容,请写评论。

之所以看起来可行,是因为您在更新中调用了它们,但是却喜欢创建一百万个协程,成千上万个处于暂停执行状态。