I am trying to set a gameobject to active on collision, wait a second and then set it to inactive again, but after the WaitForSeconds()
line the execution seems to stop. I have no experience with C# and Unity so this may be a beginner mistake. Any idea why this could be happening?
private IEnumerator OnCollisionEnter2D(Collision2D collidedWith) {
if (collidedWith.gameObject.tag == "Shape") {
collidedWith.transform.GetChild(0).gameObject.SetActive(true);
Object.Destroy(this.gameObject);
yield return new WaitForSeconds(1);
Debug.Log("Should have waited for 1 second");
collidedWith.transform.GetChild(0).gameObject.SetActive(false);
}
}
CodePudding user response:
You do
Object.Destroy(this.gameObject);
on this object which is running the Coroutine -> The routine is interrupted in that very same moment (when it reaches the first yield
statement) -> it never actually starts to wait ;)
You should rather have a component on the object you collide with and make sure the Coroutine is run on that one instead.
E.g. like
// Have this on your Shape objects
public class Shape : MonoBehaviour
{
private bool isCollided;
public void Collided()
{
if(!isCollided) StartCoroutine(Routine());
}
private IEnumerator Routine()
{
if(isCollided) yield break;
isCollided = true;
var child = transform.GetChild(0).gameObject;
child .SetActive(true);
yield return new WaitForSeconds(1);
child.SetActive(false);
isCollided = false;
}
}
and then rather do e.g.
private void OnCollisionEnter2D(Collision2D collidedWith)
{
if (collidedWith.gameObject.TryGetComponent<Shape>(out var shape))
{
shape.Collided();
Destroy(gameObject);
}
}