如何运行StartCoroutine一次?

时间:2017-04-17 23:30:53

标签: c# unity3d

我的脚本中的代码运行正常。但有时它在我接触刚体发生碰撞后不会下降。当它接触到另一个角落时,它会重新启动StartCoroutine。我想跑一次才能领先它。我怎么才能得到它? (更具描述性:在我的游戏中,一个球从上方落下,当被障碍物击中时它会停止3秒。我不希望它在击中一次之后再次停在该障碍物中。

public void OnCollisionEnter2D(Collision2D col)
{

     if (col.collider.CompareTag("Player"))
     {
         hitEffect.transform.position = col.contacts[0].point;
         hitEffect.gameObject.SetActive(true);
         GameManager.Instance.playerController.anim.Squeeze();
         col.gameObject.GetComponent<Rigidbody2D>().simulated = false;
         StartCoroutine (SetKinematic_Coroutine(col));
     }
}

public IEnumerator SetKinematic_Coroutine(Collision2D col) 
{
     yield return new WaitForSeconds(1f);
     col.gameObject.GetComponent<Rigidbody2D>().simulated = true;
}

3 个答案:

答案 0 :(得分:1)

你可以在停止时关闭球的碰撞器,以便在此期间不再接受任何击球。

 public IEnumerator SetKinematic_Coroutine(Collision2D col) 
 {
     //turn the collider off
    col.gameObject.GetComponent<Collider2D>().enabled = false;

     yield return new WaitForSeconds(1f);
     col.gameObject.GetComponent<Rigidbody2D>().simulated = true;

     //turn the collider back on after we have waited 
    col.gameObject.GetComponent<Collider2D>().enabled = true;
 }

答案 1 :(得分:1)

添加已经被它击中的对象列表,并且对于每次点击,检查它与之碰撞的对象是否在列表中,如果没有添加它并运行代码。

private List<Collider2D> collided = new List<Collider2D>();

public void OnCollisionEnter2D(Collision2D col) {

    if (col.collider.CompareTag("Player") && !collided.Contains(col.collider)) {
        collided.Add(col.collider);
        // ...    

Contains调用可能会给您带来麻烦,如果频繁地将多个碰撞器添加到列表中,否则应该这样做。

答案 2 :(得分:1)

防止协同程序多次调用的最佳方法是使用引用:

private IEnumerator coroutine = null;

private void Method()
{
    if(condition == true && this coroutine == null)
    {
        this.coroutine = MyCoroutine();
        StartCoroutine(this.coroutine);
    }
}

private IEnumerator MyCoroutine()
{
     yield return null;
     this.coroutine = null; // Set it back to null when leaving the coroutine.
}

当满足条件并且协程为空(您尚未运行它)时,它将分配给引用并调用协程的开始。协同程序正在运行时,this.coroutine不为null,并且不再满足双重条件。当协程完成时,this.coroutine被设置为null,因此下次运行双重条件时,它们都将为真。

您还可以使用基本布尔值作为标志,但也可以使用IEnumerator引用来取消。