Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
1
Question by orchard800 · Sep 22, 2015 at 10:43 AM · collidertriggerenemy health

How to handle enemy dying inside trigger collider?

I've created a simple target management system that keeps a list of enemies inside the player's trigger collider. The first item in the list is the current target and the target lock is placed in this gameobject.. and so on.

The problem is when an enemy dies inside the trigger collider. It doesn't produce an OnTriggerExit event and so never leaves the target's list. So how do I tell my player that that enemy no longer exists?

Any advice greatly appreciated.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by graciasluigi · Sep 22, 2015 at 12:01 PM

Seems right IMO that the enemy doesn't exited the trigger, he is still there, doesn't matter that he is dead. I think you need to tell your player that the enemy is dead in another way.

  • With a flag, state;

  • You can predict that the enemy will die when attacking it;

  • You can register your player to a callback(delegate) in the enemy, or in some manager. When the enemy dies, it dispatch this delegate, then the player will know that a specific enemy just died.

Lets try one example, could be something like this. But I believe that there is a lot of ways you could do what you want. You can have a central manager script, where enemies call a method to tell that they died. Etc.

Delegate is a function pointer. Awesome to work with, dependency injection, lambda expressions, functional programming. I recommend you learning it, might not be the best option for now, but of course you will need it in other cases. :)

 public class EnemyHealth
 {
     // Action<T> is a built in C# generic delegate
     public Action<EnemyHealth> GotKilled;
     
     public void TakeDamage()
     {
         ...
         if(damageKilled)
         {
             isDead = true;
         
             // If there is someone registered in the Action/delegate
             if(GotKilled != null)
             {
                              // Tell that I died
                 GotKilled(this);
             }
         }
     }
 }
 
 public class PlayerTargeting
 {
     private void OnTriggerEnter(Collider other)
     {
         ...
         // Register
         enemyTriggered.GotKilled += EnemyGotKilled;
         ...
     }
     
     private void OnTriggerExit(Collider other)
     {
         ...
         // Unregister
         enemyTriggered.GotKilled -= EnemyGotKilled;
         ...
     }
     
     private void EnemyGotKilled(EnemyHealth enemyHealthKilled)
     {
         // Remove from list, etc
     }
 }
Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image orchard800 · Sep 23, 2015 at 12:36 AM 0
Share

Thanks for the answer @garcialuigi ! Certainly given me a lot to go on. I wasn't aware of delegates until now and have spent the day reading up on them.. or at least trying, From what I've read, it's the best way forward - but I really cant get my head around the concept.

You can register your player to a callback(delegate) in the enemy, or in some manager. When the enemy dies, it dispatch this delegate, then the player will know that a specific enemy just died. public Action Got$$anonymous$$illed;

I'd be really, really grateful if you could elaborate on this.

To help put the example in context, I'm building a clone of the old TPS Desert Strike game. I have a player with a PlayerTargeting script (which manages the list of targets based on Ontrigger enter and exit events). And, I have enemies, which have EnemyHealth (has public TakeDamage method) and EnemyHUD (manages health bar per enemy) scripts attached.

How would the delegate technique fit in here?

Thanks again, Dave

avatar image graciasluigi orchard800 · Sep 23, 2015 at 02:01 AM 0
Share

Updated, trying an example.

avatar image orchard800 · Sep 24, 2015 at 02:49 AM 0
Share

Updated comment

Hi @garcialuigi. This is great - thanks for the explanation.

So, I've been away and studied a lot more about delegates. although it's still not 100% clear in my head, I'm a lot closer. I've also implemented your example code in my game but I cant figure out what 'enemyTriggered' is, in;

 enemyTriggered.Got$$anonymous$$illed += EnemyGot$$anonymous$$illed;


I've tried other.gameobject.Got$$anonymous$$illed += EnemyGot$$anonymous$$illed but it doesn't like that either.

What object does Got$$anonymous$$illed belong to in my trigger events??

Thanks again!

avatar image
3

Answer by orchard800 · Sep 25, 2015 at 09:09 PM

I'm not sure why I cant get the above working.. Anyway, I've put the effort into really learning about events and delegates, by watching and reading as many different tutorials as possible. All thanks to @garcialuigi pointing me in the right direction. To finally understand it now (at least at a fundamental level) is hugely rewarding and feels great!

So, for anyone following and looking to do similar, here's the trimmed final code that is tested and working.

 // EnemyHealth.cs with unrelated stuff removed
 
 public class EnemyHealth : MonoBehaviour     
 {
     // Set up a delegate called onDeathAction which passes on the enemy GameObject.
     // ie tell it which enemy has died
     public delegate void OnDeathAction(GameObject enemy);
 
     // Set up the event called OnDeath to be published, using the delegate OnDeathAction
     public static event OnDeathAction OnDeath; 
 
     ...
     
     public void TakeDamage(int amount)
     {
 
         ...
 
         if (currentHealth <= 0) 
         {
             // if OnDeath has subscribers. 
             // ie functions in other classes registered to listen for the event
             if(OnDeath != null)
             {
                 // Announce enemy death to subscibers
                 OnDeath(this.gameObject);
             }
             ...
         }
     }    
 }

and

 // PlayerTargeting.cs with unrelated stuff removed
 
 public class PlayerTargeting : MonoBehaviour {
 
     // set up variable for new list
     public List<GameObject> acquiredTargets;
 
     // set up variable for selected target
     public GameObject selectedTarget; 
 
     void Awake ()
     {
         // create new targets list
         acquiredTargets = new List<GameObject>();
     }
 
 
     void OnTriggerEnter(Collider col)
     {
         //if collision tagged as enemy and target is not already in targets list
         if (col.tag == "Enemy" && !acquiredTargets.Contains (col.gameObject))
         {
             // add target to targets list
             acquiredTargets.Add (col.gameObject);        
 
             // Register EnemyDied function with OnDeath event in EnemyHealth
             // ie Do EnemyDied() when OnDeath event occurs
             EnemyHealth.OnDeath += EnemyDied;
 
 
             // Refresh Targets list
             // makes sure selected target = acquiredtargetslist[0]
             UpdateSelectedTarget();
 
         }
     }
     
         
     void OnTriggerExit(Collider col)
     {
         //if collision tagged as enemy and target is not already in targets list
         if (col.tag == "Enemy" && acquiredTargets.Contains (col.gameObject))         
         { 
             // remove target from list
             acquiredTargets.Remove (col.gameObject);        
 
             // Unregister EnemyDied function with OnDeath event in EnemyHealth
             // ie Don't do EnemyDied() when OnDeath event occurs
             EnemyHealth.OnDeath  -= EnemyDied;
 
             // Refresh Targets list
             UpdateSelectedTarget();
         }
     }
 
 
     
     public void EnemyDied(GameObject enemy) /* Note the same parameters as the delegate */
     {
         // if dead target is in list
         if(acquiredTargets.Contains(enemy))
         {
             // Remove dead target from targets list
             acquiredTargets.Remove(enemy);
         }
 
         // Refresh Targets list
         UpdateSelectedTarget();
     }
 }

Hope this helps someone!

Thanks, Dave

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image graciasluigi · Sep 25, 2015 at 10:48 PM 0
Share

Awesome dude, looks like you got it. :) $$anonymous$$akes more sense the OnDeath delegate field being static as you did, though.

avatar image IronKeep · Jan 27, 2017 at 09:10 PM 0
Share

Thank you so much. This worked perfect for my little tower defense game.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

How to make an object move to the direction in which the user faces using vr gaze interaction? 1 Answer

Triggers colliding with triggers 1 Answer

What do i do if i have problems with tags? 1 Answer

Calling "OnTriggerEnter" when a parent object has a rigidbody 0 Answers

Trigger collider change fog color 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges