Introduction to Physics in Unity’ & ‘OnCollisionEnter Vs. OnTriggerEnter

by Lance Gold

— When to use them?

Return to index
Here is the short list to add a game character to Unity. Box collider in the Inspector

Box collider in the Inspector

(a) create new primitive 3D shape.

(b) organize it as a Prefab.

(c) attach a Script to the Prefab.

(d) add C# behavior code.

(e) set collision detail.

(f) set Rigidbody detail.

(g) add Tag names to GameObjects for easier coding.

(h) add C# collision code.

The C# behavior code would include positioning, random settings,

Create or Duplicate 3D shape

Duplicate an existing primitive. This is why it’s okay to move through the development process with cubes and capsules until the logic is done.

Duplicate existing game object

Duplicate existing game object

Change the scale and Material Albedo (color) to recognize the new gameObject from the existing ones. Drag the new Enemy_mat onto the new object in the Hierarchy.

0.75 scale

0.75 scale

new Material

new Material

new color, new Albedo

new color, new Albedo

Update the name to Enemy. Here we are adding a new character (gameObject) named Enemy.

Make the new gameObject a Prefab

Enemy is the name of our new object, so drag the Enemy in the Hierarchy down to the Prefabs in the Project Assets.

New Prefab

New Prefab

Attach a new Script to the Prefab

Attach to the Prefab, not to the object in the Game Hierarchy. Right click on the Prefab Enemy, Create “C# Script”.

new script

new script

In our example, the Enemy cube was a Duplicate of the Player cube. The player object has Script “Player,” so the Enemy has Script “Player.” The Prefabs object also has Script “Player.”

Remove the Player Script from the Enemy Object (in Hierarchy), click the 3-dot icon to see the menu.

remove Player (Script) component

remove Player (Script) component

After removing the Player Script from the Enemy (in Hierarchy), remove the script from the Prefabs after clicking on “Overrides — Apply all.”

Now with the Player Script removed from the Game and Prefabs, drag the Enemy Script onto the Enemy Prefabs.

…(or onto the Game Enemy object and click Overrides — Apply all.)

Enemy Prefab with Enemy Script, C# script

Enemy Prefab with Enemy Script, C# script

Make sure the Hierarchy Game Enemy has the Enemy Script, and the Project Assets Prefabs Enemy has the Enemy Script.

Add C# Behaviors to Script

Double click the Scripts Enemy to enter Visual Studio and start coding.

Remember to code in the Enemy tab, not the Player or Laser tab.

Enemy tab of Visual Studio

Enemy tab of Visual Studio

Unity Random Value

The Scripting API is helpful with a float value in a range:


myRandom = UnityEngine.Random.Range(_leftEdge, _rightEdge);
// specify UnityEngine to ovid the conflict with System.Random.Range()

Enabling Unity Physics for Collisions

Objects have a Collider Component. In the component are Trigger and Physic material options. A hard collision happens when two objects meet and stop or bounce off of each other when the Colliders meet. A trigger collision happens when the two Colliders meet and trigger without any physics used to stop or bounce. The trigger then triggers code to handle the meeting of the two objects. The code could be a change in color, a vanishing object, or a addition of the object to an inventory.

Box Collider component

Box Collider component

In this example. The “Enemy” object should disappear after a collision with a “Laser” object. There is no bounce using Collider Physics.

Is Trigger box checked in Collider component

Is Trigger box checked in Collider component

We want a Laser to disappear when colliding with an Enemy. We want a damage count when an Enemy collides with a Player object. All three have the “Is Trigger” box checked. These no-bounce collisions are “pass through” collisions.

In a pass through collision, one of the two objects needs to have a Rigid Body.

Unity has helper methods for collisions, same as how “void Start” and “void Update” are helper methods, inheriting from Monobehaviour

MonoBehaviour

class in UnityEngine

Inherits from:Behaviour

Implemented in:UnityEngine.CoreModule

Description

MonoBehaviour is the base class from which every Unity script derives.

When you use C#, you must explicitly derive from MonoBehaviour.

Deriving from MonoBehaviour allows Unity to issue messages. The important message needed are OnTriggerEnter, OnTriggerStay, OntriggerExit:

OnTriggerEnter

When a GameObject collides with an other GameObject, Unity calls OnTriggerEnter.

Laser collides with Enemy, add a Rigidbody to Laser.

Enemy collides with Player, add same for Enemy.

Add Rigidbody component

Add Rigidbody component

Uncheck the “Use Gravity” box.

Messaging C# code


public class Enemy : MonoBehaviour
{
   private void OnTriggerEnter(Collider other)
    {
        
    }
}

When the Monobehaviour sends out the OnTriggerEnter message, “other” will contain the info of “who collided with Enemy.”

“other” is a variable (a parameter); it holds Collider information.


    private void OnTriggerEnter(Collider other)
    {
        Debug.Log("Hit: " + other.transform.name);
    }

Here are two Log() messages after a game run to hit the Player with an Enemy, and then hit the Enemy with a Laser

Two Debug.Log messages

Two Debug.Log messages

Unity has a tool named ‘Tags’ to help with the destruction process.


    private void OnTriggerEnter(Collider other)
    {
        Debug.Log("Hit: " + other.transform.name);
    }

Tags let you define objects to go into “other”

(a) highlight Player in Hierarchy. Player Tag Player.

Add Tag Player to Player in Hierarchy

Add Tag Player to Player in Hierarchy

Click icon to add a new Tag for Enemy

Add a new Tag from Untagged menu

Add a new Tag from Untagged menu

Click “Add Tag…” from Untagged drop down.

Click ‘+’ to type Tag Name

Click ‘+’ to type Tag Name

Type in Enemy for New tag name

Type in Enemy as New Tag Name

Type in Enemy as New Tag Name

Click Save

Tags list with Enemy

Tags list with Enemy

That takes care of object Player. Now Tag Enemy with Enemy.

Tag Enemy from Hierarchy with Enemy

Tag Enemy from Hierarchy with Enemy

And remember to click Overrides All and Save

Remember to "Apply All” to Tag “Overrides”

Remember to “Apply All” to Tag “Overrides”

If “Enemy” was deleted from the Hierarchy Game list, then Tag Enemy to Enemy in the Prefabs.

Enemy Tag Enemy from Prefabs

Enemy Tag Enemy from Prefabs

Review Tags

Tags review

Tags review

And in this example, the same for the Laser in Prefabs.

Adding New Tag Name to Laser

Adding New Tag Name to Laser

Laser appears in the list of Tags.

Laser appears in list of Tags

Laser appears in list of Tags

Now Tag Laser (from list) to Laser (the Prefab)

Tag Laser to Laser, from list to object

Tag Laser to Laser, from list to object

Here is one way to work with Tag named GameObjects in a script:


public class Enemy : MonoBehaviour
{
    private void OnTriggerEnter(Collider other)
    {
        //Debug.Log("Hit: " + other.transform.name);

        // if 'other' contains Player, destroy this (Enemy), damage Player - Player first
        
        if (other.transform.name == "Player")
        {
            Debug.Log("Hit: Player");
            Destroy(GameObject.FindWithTag("Enemy"));
        }
        // if 'other' contains Laser, destroy this (Enemy), destroy Laser - Laser first
        if (other.transform.name == "Laser(Clone)")
        {
            Debug.Log("Hit: Laser(Clone)");
            Destroy(GameObject.FindWithTag("Laser"));
            Destroy(GameObject.FindWithTag("Enemy"));
        }

    }
}

Here is a shorter version using “other.tag”:


public class Enemy : MonoBehaviour
{
    private void OnTriggerEnter(Collider other)
    {
        //Debug.Log("Hit: " + other.transform.name);

        // if 'other' contains Player, destroy this (Enemy), damage Player - Player first
        
        if (other.tag == "Player")
        {
            Destroy(this.gameObject);  // Enemy
        }
        // if 'other' contains Laser, destroy this (Enemy), destroy Laser - Laser first
        if (other.tag == "Laser")
        {
            Destroy(other.gameObject);
            Destroy(this.gameObject);
        }

    }
}