Collision detection not working + objects seem not at the same layer

Hello everyone,

I’m currently working on a project where I need the ship and asteroid to disappear after colliding and then regenerate after a few seconds. However, I’m facing an issue where the ship and asteroid don’t seem to react upon collision. Additionally, there’s no output in the debug log for the collision, which indicates that they are not colliding at all.

In the main camera view, the asteroid appears to float right over the ship, almost as if they are not on the same layer. I’ve ensured that the rigidbody y-axis is locked, the tags are correctly set, and I’ve checked the “cross-grids” in the layer collision settings, but the problem persists.

I would greatly appreciate any insights or advice on what might be going wrong. Below, I’ve included the scripts for both the asteroid and the ship (which contains the logic for the ship disappearing after colliding with the asteroid).

Thank you in advance for your help!

Asteroid.cs

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

public class Asteroid : MonoBehaviour
{
    public GameObject smallAsteroidPrefab; // Reference to the smaller asteroid prefab (only for large asteroids)
    private Rigidbody rigidBody; // We will automatically get this in Start
    private bool canSplit = true; // A flag to check if the asteroid can still split

    void Start()
    {
        // Automatically get the Rigidbody component attached to this GameObject
        rigidBody = GetComponent<Rigidbody>();

        // Randomize size and mass
        transform.localScale = new Vector3(Random.Range(0.08f, 0.12f), Random.Range(0.08f, 0.12f), Random.Range(0.08f, 0.12f));
        rigidBody.mass = transform.localScale.x * transform.localScale.y * transform.localScale.z;

        // Randomize velocity
        rigidBody.velocity = new Vector3(Random.Range(-10f, 10f), 0f, Random.Range(-10f, 10f));
        rigidBody.angularVelocity = new Vector3(Random.Range(-4f, 4f), Random.Range(-4f, 4f), Random.Range(-4f, 4f));

        // Check if the asteroid is too small to split
        if (transform.localScale.x <= 0.05f) 
        {
            canSplit = false; // If it's too small, it can't split anymore
        }
    }

    private void OnCollisionEnter(Collision collision)
    {
        // Check if the asteroid was hit by a bullet
        if (collision.gameObject.CompareTag("Bullet"))
        {
            Destroy(collision.gameObject); // Destroy the bullet
            
            if (canSplit && smallAsteroidPrefab != null) // Only split if it's large enough and the prefab is assigned
            {
                SpawnFragmentsOrSmallAsteroids(); // Handle asteroid splitting or destruction
            }
            else
            {
                Destroy(gameObject); // Directly destroy the small asteroid
            }
        }
    }

    // Spawn smaller asteroids or debris when the asteroid is hit by a bullet
    void SpawnFragmentsOrSmallAsteroids()
    {
        if (transform.localScale.x > 0.1f && smallAsteroidPrefab != null) // Only if large enough and prefab exists
        {
            // Split into smaller asteroids
            for (int i = 0; i < 2; i++) // Create two smaller asteroids
            {
                GameObject smallAsteroid = Instantiate(smallAsteroidPrefab, transform.position, Quaternion.identity);
                smallAsteroid.transform.localScale = transform.localScale * 0.5f; // Scale down the smaller asteroid
                smallAsteroid.GetComponent<Rigidbody>().velocity = new Vector3(Random.Range(-5f, 5f), 0f, Random.Range(-5f, 5f));

                // Ensure the smaller asteroids don't keep splitting
                Asteroid smallAsteroidScript = smallAsteroid.GetComponent<Asteroid>();
                if (smallAsteroidScript != null)
                {
                    smallAsteroidScript.canSplit = false; // Disable splitting for the smaller asteroids
                }
            }
            Destroy(gameObject); // Destroy the original large asteroid
        }
        else
        {
            // If the asteroid is already small or no prefab is set, destroy it completely
            Destroy(gameObject);
        }
    }
}

Spaceship.cs

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

public class Spaceship : MonoBehaviour
{
    private Rigidbody rigid;
    
    // Bullet-related variables
    public GameObject bulletPrefab;
    public Transform bulletSpawnPoint;
    public float bulletSpeed = 20f;
    private float fireRate = 0.25f; // Time between shots (4 shots per second)
    private float nextFireTime = 0f; // Tracks when the next bullet can be fired
    
    void Start()
    {
        rigid = GetComponent<Rigidbody>();
    }

    void Update()
    {
        if (Input.GetKey(KeyCode.UpArrow))
            rigid.AddForce(transform.forward * (rigid.mass * Time.fixedDeltaTime * 2000f));

        if (Input.GetKey(KeyCode.LeftArrow))
            rigid.AddTorque(-Vector3.up * (rigid.mass * Time.fixedDeltaTime * 4000f));
        else if (Input.GetKey(KeyCode.RightArrow))
            rigid.AddTorque(Vector3.up * (rigid.mass * Time.fixedDeltaTime * 4000f));

        // Fire bullet if space is pressed and it's time to fire again
        if (Input.GetKeyDown(KeyCode.Space) && Time.time >= nextFireTime)
        {
            FireBullet();
            nextFireTime = Time.time + fireRate; // Set the next allowed fire time
        }
    }

    // Function to fire a bullet
    void FireBullet()
    {
        // Instantiate a new bullet at the bulletSpawnPoint position and rotation
        GameObject bullet = Instantiate(bulletPrefab, bulletSpawnPoint.position, bulletSpawnPoint.rotation);

        // Get the Rigidbody component of the bullet
        Rigidbody bulletRb = bullet.GetComponent<Rigidbody>();

        // Apply velocity to the bullet in the forward direction of the spaceship
        bulletRb.velocity = transform.forward * bulletSpeed;
    }

    // Handle collision with Asteroids
    private void OnCollisionEnter(Collision collision)
    {
        // Check if the spaceship collides with an asteroid
        if (collision.gameObject.CompareTag("Asteroid"))
        {
            Debug.Log("Spaceship hit by an asteroid!");

            Destroy(gameObject); // Destroy the spaceship
            RespawnPlayer(); // Respawn after a delay
        }
    }

    // Respawn the player ship at the center of the screen with a delay
    void RespawnPlayer()
    {
        StartCoroutine(RespawnWithDelay(2f)); // 2-second delay before respawning
    }

    IEnumerator RespawnWithDelay(float delayTime)
    {
        yield return new WaitForSeconds(delayTime); // Wait for the delay time
        GameObject player = Instantiate(GameManager.instance.spaceshipPrefab, Vector3.zero, Quaternion.identity); // Respawn at center
    }
}

If you need any further info for solving this problem, just ask me! Thanks :pray:

Can you screenshot the inspectors of both objects involved in the collision?
Make sure neither colliders have Trigger set.

Also you might have some luck going through my troubleshooting resource:


Also, if public GameObject bulletPrefab; was public Rigidbody bulletPrefab; (and you re-assigned the reference), you could remove the Rigidbody bulletRb = bullet.GetComponent<Rigidbody>(); line and assign the result of Instantiate directly to bulletRb. There’s usually little reason to reference GameObjects unless you intend to activate/deactivate them.

This is the screenshot of the inspector of spaceship(the inspector is below, because the forum limits me for only one image in a reply:(

And this is the inspector of the asteroid, thank you vertxxyz!

There is no mesh assigned to this mesh collider. I’m honestly surprised there isn’t a warning for this

Thank you so much. I‘ve add mesh to my spaceflight and SpaceshipContainer(parent object). It can run collision debug log now(Spaceship hit by an asteroid)!