- Home /
how can I add a second ontriggerenter to my bullet script?
I have a tower that has a bullet prefab attached to it. The bullet has a script which deals damage to 1 type of enemy.using ontriggerenter. I want to be able to have multiple types of enemies but i can't have more than 1 ontriggerenter on my bullet script. How could i do this so my bullet can attack more than 1 type of enemy?
The key is to have all your enemies inherit a common Enemy component, that way your bullet will hit any kind of enemy.
Answer by Waka-Takaki · Jun 13, 2016 at 07:35 AM
Your OnTriggerEnter()
is called every time your bullet trigger collider enters another collider, not only the one with a component called MonsterHealth
. Currently anytime your bullet hits any object it will attempt to find a MonsterHealth component, which will return a Null if it doesn't exist. If you want to check what was collided with then use an if statement in the OnTriggerEnter
method. Something like this:
void OnTriggerEnter(Collider co) {
if(co.gameObject.name == "monster") {
//Reduce its health
}
else if(co.gameObject.name == "wereWolf") {
//Do something else
}
}
BETTER
By the way, it would be better to have a generic Health
script on any type of enemy that can take damage, which just stores the enemy health and can reduce it. In the OnTriggerEnter
method just find this script and it will be able to damage anything you give that script to, without using a clumsy if/else statement as above.
Example: Create a script called Health as below:
using UnityEngine;
using System.Collections;
public class Health : MonoBehaviour {
int health;
public void Damage() {
health -= 1;
if(health <=0) {
Die();
}
}
void Die() {
//Do anything you need to do during death
//then:
Destroy(gameObject);
}
}
then attach this to all of your objects you want to take damage.
In your bullet script:
void OnTriggerEnter(Collider co) {
Health health;
if(health = co.GetComponent<Health>()) {
//Reduce its health
health.Damage();
}
}
while it's true that the code will attempt to get the "$$anonymous$$onsterHealth" component of every object that enters the trigger, it won't throw a null reference exception since he has a null check:
if (health)
GetComponentInChildren will simply return null if no component could be found. null is a perfect valid value. You just shouldn't try to use that reference to access the referenced object. That would cause a null reference excetion. Such an exception is thrown whenever you follow a null-reference and try to access the referenced object.
Using GetComponent / GetComponentInChildren is actually much more flexible than checking the object's name / tag. The code works for any object that has that component attached and does nothing on objects that don't have that component.
@Bunny83 you're right I missed the if (health) check, I have edited to clarify. See the second part of my answer and I describe a better alternative. I was answering the question as simply as possible first.
Answer by ninja_gear · Jun 13, 2016 at 02:14 PM
EDIT: Sorry, I read the comments before I understood your question:
You need to make it so all your enemies share a common 'enemy' component. then have every enemy inherit that component. Now when your bullet hits things, it doesn't have to worry about what kind of enemy it is, it just hits anything that is an enemy.
public class Enemy : MonoBehavior
{
//has health
}
public class Werewolf : Enemy
{
//does Werewolf stuff
}
public class Vampire : Enemy
{
//does Vampire stuff
}
Answer by Brijs · Jun 13, 2016 at 08:56 AM
Here you can give tag from inspector to each enemy and in OnTriggerEnter method filter triggered object tag wise
For example......
If you have given tag "enemy1" to type 1 enemy and "enemy2" to type 2 enemy then your code of OnTriggerEnter can be like
void OnTriggerEnter(Collider other) {
if(other.gameObject.tag== "enemy1") {
//Code goes here
}
else if(other.gameObject.tag== "enemy2") {
//Code goes here
}
}
@Brijs - this is a good approach, but youd have to end up creating a lot of tags, especially if he is spawning enemies by script, assigning a new tag to every single enemy might get confusing and inefficient - an alternative could be ins$$anonymous$$d of checking the objects tag, check the objects name - and for every enemy that is created, either rename it to add a number at the end, or use Unity's auto-increment method for objects with the same name and check by that way ins$$anonymous$$d.
He could also use a List array with OnTriggerStay, and then attack every enemy found in that array in OnTriggerEnter - and for more accurate attacking, remove the enemies that leave the range in OnTriggerExit. I often use this method with AI to have them attack multiple targets at the same time and logically prioritize who should be hit first (based on closeness, and health)
If we give tag to each type of enemy prefabthen we can filter enemy type in OnTirggerEnter with this approach. If we talk about enemy type that number is less and if we talk about total number of enemies then number is very high so this approach of setting tag is good approach.
I must of mis-understood the original question then - to me it sounds like when he says "multiple types of enemies" he is referring to tracking more than one enemy at the same time, not 2 enemies with completely separate tags. $$anonymous$$isinterpretation I guess.
Answer by JatsArts · Jun 13, 2016 at 05:48 PM
There are probably better ways to do this, and I'm looking forward to find out what they are, but in the mean time this is what I usually do. Just an example:
using UnityEngine;
class EnemyType
{
}
class EnemyType1:EnemyType
{
}
class EnemyType2:EnemyType
{
}
public class Bullet : MonoBehaviour
{
void DamageEnemy (EnemyType1 enemy)
{
//blah
}
void DamageEnemy (EnemyType2 enemy)
{
//blah
}
void OnTriggerEnter (Collider coll)
{
var other = coll.gameObject;
EnemyType1 enemyType1 = other.GetComponent<EnemyType1> ();
if (enemyType1 != null) {
DamageEnemy (enemyType1);
}
EnemyType2 enemyType2 = other.GetComponent<EnemyType2> ();
if (enemyType2 != null) {
DamageEnemy (enemyType2);
}
}
}
Your answer
Follow this Question
Related Questions
OnTriggerEnter help 2 Answers
How do I change scene with OnTriggerEnter with thrid person controller? 2 Answers
Check OnTrigger for component 1 Answer
Why isn't my tag working (on trigger enter) 2 Answers
Issues with collision detection 2 Answers