Search Unity

1 OnTriggerEnter, 2 similar objects, just 1 trigger works :(

Discussion in 'Scripting' started by KevS, Jan 8, 2012.

  1. KevS

    KevS

    Joined:
    Apr 21, 2010
    Posts:
    51
    Hi !
    I know there are many questions about this, but i can't find an answer, and I can't find a solution myself :(

    Well here is my situation.
    I have :

    • 1 spaceship, with a rigidbody and a script with the OnTriggerEnter function implemented.
    • 1 Child with just a box collider set as a trigger.
    • 2 Types of game object to collide with. An other ship and the laser of this ship. Both have rigidbodies, colliders as triggers and are in the same layer + a script with a OnTriggerEnter function with just "Destroy(gameObject)" ... so almost the same things.

    My problem : When my spaceship collide with the others ships, OnTriggerEnter is called, not with the laser.But the collision happen because both, laser and ship are destroyed by their own OnTriggerEnter.

    I try different thing to understand, and if I put my "OnTriggerEnter" script on the child collider of my spaceship, the laser trigger the function, but no the others ships ?!

    Any idea ?
     
  2. kingcharizard

    kingcharizard

    Joined:
    Jun 30, 2011
    Posts:
    1,137
    Can you show the code. I think i have an idea of your problem but i'd need to see the code..
     
  3. KevS

    KevS

    Joined:
    Apr 21, 2010
    Posts:
    51
    No problemo, the code is quite simple :

    Script on the player spaceship which suppose to handle the collision

    Code (csharp):
    1.  
    2. public class HealthController : MonoBehaviour
    3. {
    4.     public int lifeNumberMax = 3;
    5.     public int touchesMax = 3;
    6.     public int lifeNumber;
    7.     public int touchRemaining;
    8.     public Transform model;
    9.     public Transform respawnLocation;
    10.  
    11.     public bool isInvicible;
    12.     private Color mainColor;
    13.  
    14.     void Start()
    15.     {
    16.         lifeNumber = lifeNumberMax;
    17.         touchRemaining = touchesMax;
    18.     }
    19.  
    20.     void OnTriggerEnter(Collider other)
    21.     {
    22.         //Debug.Log(other.name);
    23.         if (other.tag == "Enemy")
    24.         {
    25.             OnEnemyHit();
    26.         }
    27.     }
    28.  
    29.     void OnTriggerExit(Collider other)
    30.     {
    31.  
    32.     }
    33.  
    34.     private void OnEnemyHit()
    35.     {
    36.         if (!isInvicible)
    37.         {
    38.             if (touchRemaining == 1)
    39.             {
    40.                 Kill();
    41.             }
    42.             else
    43.             {
    44.                 --touchRemaining;
    45.             }
    46.         }
    47.     }
    48.  
    49.     private void Kill()
    50.     {
    51.         if (lifeNumber == 1)
    52.         {
    53.             GameOver();
    54.         }
    55.         else
    56.         {
    57.             --lifeNumber;
    58.             Respawn();
    59.         }
    60.     }
    61.  
    62.     private void GameOver()
    63.     {
    64.         Application.LoadLevel(0);
    65.     }
    66.  
    67.     private void Respawn()
    68.     {
    69.         touchRemaining = touchesMax;
    70.         transform.position = respawnLocation.position;
    71.     }
    72.  
    73.     void OnGUI()
    74.     {
    75.         GUI.Label(new Rect(0, 0, 100, 25), "Life Left : " + lifeNumber);
    76.         GUI.Label(new Rect(0, 25, 100, 25), "Energy Left : " + touchRemaining);
    77.         GUI.Label(new Rect(0, 80, 250, 30), "Controls : Move -> Arrow, Fire -> W");
    78.     }
    79. }
    80.  
    The code on the enemy ship

    Code (csharp):
    1.  
    2. public class Enemy : MonoBehaviour
    3. {
    4.     public float health = 100;
    5.  
    6.     //Attack Fields
    7.     public float attackSpeed = 0.1f;
    8.     public Transform ammo;
    9.     private float nextFire = 0;
    10.     public bool firing;
    11.  
    12.     void Update()
    13.     {
    14.         if ((Time.time > nextFire)  firing)
    15.         {
    16.             Fire();
    17.         }
    18.     }
    19.  
    20.     private void Fire()
    21.     {
    22.         Transform bullet = (Transform)Instantiate(ammo, transform.position, transform.rotation);
    23.         nextFire = Time.time + attackSpeed;
    24.     }
    25.  
    26.     void OnTriggerEnter(Collider other)
    27.     {
    28.         if (other.tag == "Projectile")
    29.         {
    30.             health -= 100;
    31.             if (health <= 0)
    32.             {
    33.                 Kill();
    34.             }
    35.         }
    36.         else if (other.tag == "Player")
    37.         {
    38.             health -= 100;
    39.             if (health <= 0)
    40.             {
    41.                 Kill();
    42.             }
    43.         }
    44.         else if (other.tag == "Activator")
    45.         {
    46.             firing = true;
    47.         }
    48.     }
    49.  
    50.     public void Kill()
    51.     {
    52.         Destroy(gameObject);
    53.     }
    54. }
    55.  
    And the code on the "laser", kind of bullet instantiate by the enemy ship

    Code (csharp):
    1.  
    2. public class Projectile : MonoBehaviour
    3. {
    4.     public int damage = 10;
    5.     public float lifeTime = 10;
    6.     public float speed = 20;
    7.  
    8.     void Start()
    9.     {
    10.         rigidbody.velocity = transform.up * speed;
    11.         Invoke("Kill", lifeTime);
    12.     }
    13.  
    14.     void OnTriggerEnter(Collider other)
    15.     {
    16.         //Debug.Log(other.name);
    17.         Kill();
    18.     }
    19.  
    20.     public void Kill()
    21.     {
    22.         Destroy(gameObject);
    23.     }
    24. }
    25.  
    You can see in the first script HealthController, that OnEnemyHit is call only if the other is tagged as Enemy, and the enemy ship and laser are tagged "Enemy", i'm sure :)

    And all collisions happens, it's just that OnTriggerEnter is only call with the collision with the enemy, not with the "projectile".
     
  4. kingcharizard

    kingcharizard

    Joined:
    Jun 30, 2011
    Posts:
    1,137
    try{
    Is your projectile tagged projectile?
    Is your projectile and enemy at the same depth in 3d space(Are they colliding)?
    does the projectile have a non kinematic rigidbody attached?
    }
    Code (csharp):
    1.  void OnTriggerEnter(Collider other)
    2.     {
    3.         if (other.tag == "Projectile")
    4.         {
    5.             health -= 100;
    6.             if (health <= 0)
    7.             {
    8.                 Kill();
    9.             }
    10.         }
    11.         else if (other.tag == "Player")
    12.         {
    13.             health -= 100;
    14.             if (health <= 0)
    15.             {
    16.                 Kill();
    17.             }
    18.         }
    ^^Take out the last else if and see what happens....

    Obviously your problem is in the enemy script
     
    Last edited: Jan 8, 2012
  5. KevS

    KevS

    Joined:
    Apr 21, 2010
    Posts:
    51
    Thanks for the reply.

    Have some new elements to deal with :

    If I put the collider which is as a child on the parent (the game object with the rigidbody), all works fine.
    If I keep the collider as a child and if I add a script with the OnTriggerEnter function, the function is called.
    In other words, the same collider trigger the function in one case to the rigidbody and in the other to the collider itself

    In the doc it says :
    function OnTriggerEnter (other : Collider) : void
    " This message is sent to the trigger collider and the rigidbody (or the collider if there is no rigidbody) that touches the trigger"
    And the "Compound Colliders" is a recommendation of the doc too :
    http://unity3d.com/support/documentation/Components/class-BoxCollider.html

    I read somewhere that Triggers are only send to the collider component, not to the rigidbody, but in my case, it depends ... and I can't determine why, because the 2 objets which collide are build in the same way : 1 rigibody, 1 trigger on the same game objets (no child)