Using StartCoroutine / IEnumerator to Temporarily Disable Collider on Spawn.

I am trying to have my player game object have its Collider2D disabled for a short period of time right after spawning and then re-enabled there by giving the player a few seconds to re position to avoid chain spawn deaths. The code I have so far is below, I am not sure if my IEnumerator working because I need to provide an argument to StartCoroutine, right now its giving me an error.The idea is player spawns, collider2d is set to inactive, 3 seconds pass, and the collider is set back to active and stays that way.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class Boundary
{
    public float xMin, xMax, yMin, yMax;
}

public class PlayerController : MonoBehaviour {

    public Boundary boundary;

    public float invTime = 3f;
  
    //Navigation Variables
    public float speed;
    public float strafespeed;

    //Weapon Variables
    public Transform shotSpawn1;
    public GameObject shot;
    public float fireRate;
    private float nextFire;
    private AudioSource audioSource;

    private Rigidbody2D rb;


    void Start ()
    {
        rb = GetComponent<Rigidbody2D>();
        audioSource = GetComponent<AudioSource>();
      
    }

    private void Awake()
    {
        StartCoroutine(Invincibility());
    }

    IEnumerator Invincibility(Collider2D collider)
    {
        GetComponent<Collider2D>().enabled = false;
        yield return new WaitForSeconds(invTime);
        GetComponent<Collider2D>().enabled = true;
      
    }

    void Update ()
    {
        if (Input.GetButton("Fire1") && Time.time > nextFire)
        {
            nextFire = Time.time + fireRate;
            Instantiate(shot, shotSpawn1.position, shotSpawn1.rotation);
            audioSource.Play();
        }
    }

    private void FixedUpdate()
    {
        var mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        Quaternion rot = Quaternion.LookRotation(transform.position - mousePosition, Vector3.forward);

        transform.rotation = rot;
        transform.eulerAngles = new Vector3(0, 0, transform.eulerAngles.z);

        float v = Input.GetAxis("Vertical");
        float h = Input.GetAxis("Horizontal");
        rb.AddForce(Vector3.up * speed * v);
        rb.AddForce(Vector3.right * strafespeed * h);

        rb.position = new Vector3
        (
           Mathf.Clamp(rb.position.x, boundary.xMin, boundary.xMax),
           Mathf.Clamp(rb.position.y, boundary.yMin, boundary.yMax),
           0.0f
        );
    }
}

You declared Invincibility() as taking a Collider2D object, but then inside you actually do a .GetComponent call to get the Collider2D.

I think what you want to do is operate on the passed-in collider, and then in the Awake() function you want to pass in the .GetComponent() as an argument to Invincibility().

The reason for the second paragraph is that once disabled, a standard old .GetComponent will actually not even find the Collider2D. You would need to pass in an extra argument to find a disabled Component in order to get it back in order to re-enable it, so why not just get the reference once, then turn it off, wait, then turn it back on with the same still-perfectly valid reference!

You could also do the GetComponent actually inside Invincibility() and store it as a local reference, then disable it, wait, then re-enable it. Either way… I’d probably do the latter because then Awake doesn’t need to know details about Invulnerability(), such as that it needs a collider, etc.

1 Like

What I ended up adding to my code is below, and it works. Thank you for your help, reading your post it only took me a minute or two to correct my code, versus the half an hour I spent trying to research how to do it.

    private Collider2D inv;


    void Start ()
    {
        rb = GetComponent<Rigidbody2D>();
        audioSource = GetComponent<AudioSource>();
        StartCoroutine(Invincibility());
    }


    IEnumerator Invincibility()
    {
        inv = GetComponent<Collider2D>();
        inv.enabled = false;
        yield return new WaitForSeconds(invTime);
        inv.enabled = true;
    }
1 Like