2D On Collision works some times but not others

Hey All,

I’m building a 2D game which involves a player shooting objects floating towards them.

However, when testing some times my colliders work and other times they don’t, and i can;t figure out why. I have a spawner that controls the spawning of game objects. the prefabs all have Colliders and Rigid bodies, 2D versions.

Code below:

Spawner

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

public class Spawner : MonoBehaviour
{
    public GameObject asteroid;
    public GameObject attack;
    private float playerX;
    private float playerY;
    private static Spawner instance;
    public static Spawner Instance
    {  get { if (instance == null) instance = GameObject.FindObjectOfType<Spawner>();  return instance; } }

    public void SpawnAsteroids()
    {
        float spawnPointX = Random.Range(20f,25f);
        float spawnPointY = Random.Range(-7.24f,7.24f);

        Vector2 spawnLocation = new Vector2(spawnPointX, spawnPointY);
        GameObject newAsteroid = Instantiate(asteroid,spawnLocation,Quaternion.identity);
        newAsteroid.name = "Asteroid";
        Debug.Log("Spawn:" + newAsteroid);
    }

    public void SpawnAttack()
    {
        playerX = Player.Instance.transform.position.x+1;
        playerY = Player.Instance.transform.position.y;


        Vector2 spawnLocation = new Vector2(playerX, playerY);
        GameObject newAttack = Instantiate(attack,spawnLocation,Quaternion.identity);
        newAttack.name = "Attack";
    }
}

Floating Object

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

public class Asteroid : MonoBehaviour
{
    private int direction = -1;
    [SerializeField] private float moveSpeed;
    private Rigidbody2D rb;

    private static Asteroid instance;
    public static Asteroid Instance
    {
        get
        {
            if (instance == null) instance = GameObject.FindObjectOfType<Asteroid>();
            return instance;

        }

    }

    private void Awake()
    {
        rb = GetComponent<Rigidbody2D>();
        float randomSpeed = Random.Range(3, 8);
        moveSpeed = randomSpeed;
    }

    // Update is called once per frame
    void Update()
    {
        if(transform.position.x < -15)
        {
            Destroy(gameObject);
        }
    }

    private void FixedUpdate()
    {
        ApplyMovement();
    }

    void ApplyMovement()
    {
        float speed = moveSpeed * Time.deltaTime;
        rb.velocity = new Vector2(moveSpeed * direction, 0);
    }

    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject == Player.Instance.gameObject) 
        {
            Player.Instance.Health -= 1;
            Destroy(gameObject);
        }else if (collision.gameObject == Attack.Instance.gameObject)
        {
            Destroy(Attack.Instance.gameObject);
            Destroy(gameObject);
        } else
        {
            Debug.Log(collision.gameObject);
        }
    }
}

Bullet

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

public class Attack : MonoBehaviour
{
    private int direction = 1;
    [SerializeField] private float moveSpeed;
    private Rigidbody2D rb;

    private static Attack instance;
    public static Attack Instance
    {
        get
        {
            if (instance == null) instance = GameObject.FindObjectOfType<Attack>();
            return instance;

        }

    }

    private void Awake()
    {
        rb = GetComponent<Rigidbody2D>();
        moveSpeed = 9;
    }

    // Update is called once per frame
    void Update()
    {
        if (transform.position.x > 15)
        {
            Destroy(gameObject);
        }
    }

    private void FixedUpdate()
    {
        ApplyMovement();
    }

    void ApplyMovement()
    {
        float speed = moveSpeed * Time.deltaTime;
        rb.velocity = new Vector2(moveSpeed * direction, 0);
    }

On the bullet’s and asteroid’s rigidbody set the collision detection mode to ‘Continuous’.

They are already set to continus, never sleep and interpolate.

What does the Debug.Log(collision.gameObject); print when it “doesn’t work?” Nothing, or some other collider?

It logs the bullet as expected.

So OnCollision2D is working just fine, your logic is bad.
You are trying to use a singleton (the coding pattern with Instance) for an object that’s instanced many times, Attack. It makes no sense.

Attack shouldn’t be a singleton, nor should Asteroid (presuming there are many of them). Use TryGetComponent, or tags to identify objects instead.

Thank you so much!!!

I have now changed the Collision2D to:

(collision.gameObject.name == "Attack")

Now it all works fine!!