Skip to content

Collision detection

Lee Seokhyun edited this page Aug 1, 2020 · 5 revisions

In this chapter, you will learn.

  • How to detect collisions

Collision between bullets and enemies

image

Open one enemy prefab in the above path. Double click it or press the Enter key.

image

There is a BoxCollider component in the Cube object. Because we will use the OnTriggerEnter method, make sure that the IsTrigger variable is checked.

The EnemyClision component is immediately below.

/// <summary>
/// EnemyCollision
/// This class implements collision between enemies and player's bullets.
/// </summary>
public class EnemyCollision : MonoBehaviour
{
    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("PlayerBullet"))
        {
            OnDamage(other.transform.position);

            // Destroy bullet.
            Destroy(other.gameObject);
        }
    }


    void OnDamage(Vector3 collisionPoint)
    {
        GetComponentInParent<Enemy>().OnDamage(collisionPoint);
    }
}

The OnTriggerEnter method to be called when the enemy has collided the bullet of a player. It is called automatically by the Engine.

The other parameter of this method means a bullet object because this class is attached to an Enemy object. You should compare the tag for the object provided through the parameter. Depending on the implementation, It could be a different object instead of the bullet.

If the object has PlayerBullet tag, it executes the OnDamage method to attack to the enemy. Let's look into the Enemy class.

/// <summary>
/// When the enemy gets damaged.
/// </summary>
/// <param name="collisionPoint"></param>
public void OnDamage(Vector3 collisionPoint)
{
    // Knockback.
    //Vector3 pos = transform.position;
    //pos.z += 0.2f;
    //transform.position = pos;

    // Instantiate the damage effect.
    GameObject.Instantiate(this.prefabDamage, collisionPoint, Quaternion.identity);

    // Blink the object.
    if (GetComponentInChildren<MaterialChanger>() != null)
    {
        GetComponentInChildren<MaterialChanger>().enabled = true;
    }

    // Decrease current hp.
    --this.currentHp;

    // If the current hp is less than zero, it will be destroyed.
    if (this.currentHp <= 0.0f)
    {
        DestroyNow();
    }
}

If you want to Knockback, remove the three comments at the first.

Collision between enemies and the player

image

/// <summary>
/// PlayerCollision
/// This class implements collision between enemies and player.
/// </summary>
public class PlayerCollision : MonoBehaviour
{
    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("EnemyBullet"))
        {
            OnDamage(other.transform.position);

            // Destroy the bullet.
            Destroy(other.gameObject);
        }
        else if (other.CompareTag("Enemy"))
        {
            OnDamage(other.transform.position);

            // Destroy the enemy.
            other.GetComponentInParent<Enemy>().DestroyNow();
        }
    }


    void OnDamage(Vector3 collisionPoint)
    {
        GetComponentInParent<Player>().DestroyNow();
    }
}

This code is almost the same as the code of the EnemyCollision.

Below is the Player code.

public class Player : MonoBehaviour
{
    [Header("Prefab explosion")]
    [SerializeField]
    GameObject prefabExplosion;


    public void DestroyNow()
    {
        // Instantiate the destroy effect.
        GameObject.Instantiate(this.prefabExplosion, transform.position, Quaternion.identity);

        // Deactivate.
        gameObject.SetActive(false);

        // Call the GameOver method.
        PlayManager.Instance.GameOver();
    }
}

Let's continue to look at the PlayManager code.

public class PlayManager : SingletonMonobehaviour<PlayManager>
{
    [SerializeField]
    Camera gameCamera;


    public void GameOver()
    {
        this.gameCamera.GetComponent<CameraShake>().enabled = true;
        StartCoroutine(ReloadCurrentScene());
    }


    IEnumerator ReloadCurrentScene()
    {
        yield return new WaitForSeconds(3.0f);

        SceneManager.LoadScene(0);
    }
}

When the GameOver method has been called, it shakes the Camera for the special effect, finally reload the current scene to restart the game.

You can see the PlayManager object in the inspector.

image

There is the MainCamera object also. The CameraShake component is attached to it. It is disabled by default because it must only be executed when the game is over.

image

Conclusion

In this document, we had learned how to detect collisions with each game object. We had learned how to restart the game when the game is over. There are many ways to do it, I had selected reloading the Scene. That way is very easy to reset all objects.