Allow a game object to pass out of a collider but not back in – Unity

Allow a game object to pass out of a collider but not back in – Unity

In my game I have enemies that shoot projectiles out at the player, the only way for the player to get rid of them is by guiding them into a structure.

An example of my enemy shooting a projectile.
The problem I have is that sometimes the enemy spawns on top of one of these structures as seen below.

This results in the projectile exploding/colliding with the structure the moment it is spawned.
I'm not entirely sure how to go about fixing this issue. 
I have tried to find a way to disable the collider on the projectile for a few seconds but I couldn't get the timer right. I also think this might cause some odd game-play issues.
The second thing I tried was a platform effector, however I could only get it to form a circle and this didn't work out because my structures are of all different sizes and shapes.
If anyone could point me into the right direction or even help me find a better solution I'd be extremely grateful.
Thanks
ublic class MultiBullet : MonoBehaviour {

    public float speed = 1f;

    private Rigidbody2D rb;

    // Use this for initialization
    void Start () {
        rb = GetComponent();

    }

    // Update is called once per frame
    void Update () {
        rb.velocity = transform.up * speed;
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        ////Add explosion Effect
        //if (collision.gameObject.tag == "Player")
        //{
        //    // Add game over screen here
        //    Debug.Log("Player Killed");
        //    Destroy(gameObject);
        //}
        ////Debug.Log("BOOM");
        ////Destroy(gameObject);
        if(collision.gameObject.tag != "BulletIgnore" && collision.gameObject.tag != "Cloud")
        {
            //Debug.Log("BOOM");
            Destroy(gameObject);
        }
    }
}

Just a simple class to handle when projectiles collide with objects.

Solutions/Answers:

Answer 1:

Overview: immediately after instantiation, check what objects the projectile overlaps. Disable collisions between those objects. Then, on each frame, re-check that list and when it no longer overlaps a collider, reenable collisions between those objects.

Warning: untested

public class ProjectileOverlapCheck : MonoBehavior {
  private Collider2D[] overlapping;
  private Collider2D[] testOutput;
  private Collider2D collider;
  private int overlappingCount;

  private void Start() {
    int max = 4; //Note: if it could be overlapping more than 4 things on the first frame, increase this number
    overlapping = new Collider2D[max];
    testOutput = new Collider2D[max];
    collider = GetComponent<Collider2D>();
    ContactFilter2D filter = new ContactFilter2D().NoFilter();
    overlappingCount = collider.OverlapCollider(filter, overlapping);
    if (overlappingCount == 0) {
      Destroy(this);
      return;
    }
    for (int i = 0; i < overlappingCount; i++) {
      Physics2D.IgnoreCollision(collider, overlapping[i], true);
    }
  }

  private void FixedUpdate() {
    ContactFilter2D filter = new ContactFilter2D().NoFilter();
    int newOverlappingCount = collider.OverlapCollider(filter, testOutput);
    for (int i = overlappingCount - 1; i >= 0; i--) {
      bool found = false;
      for (int j = 0; j < newOverlappingCount; j++) {
        if (overlapping[i] == testOutput[j]) {
          found = true;
          break;
        }
      }
      if (!found) {
        Physics2D.IgnoreCollision(collider, overlapping[i], false);
        if (--overlappingCount == 0) {
          Destroy(this);
        } else {
          overlapping[i] = overlapping[overlappingCount];
        }
      }
    }
  }
}

References