- Home /
Targets in Collider
Dear: Readers
I have this problem that has been bothering me for awhile now. Want to ask you all to see if you can help me solve it, with another perspective.
I am designing a TD game, and having problems with the que system. Right now I have it set up, as a enemy comes in the turret collider, the turret adds 1 to "counter" variable and when exits take 1 away from "counter". When "counter
The problem lays in the "counter" with enter and exit. As when a enemy gets destroyed inside a collider the turret does not register it as a exit.
Hope someone can help out with the problem, maybe even come at it with a totally new perspective.
Thank You: James
please supply the code describing the script doesn't help when it may be a simple miss type.
No he is right, when you instantiate an object inside a collider OnTriggerEnter won't be rised and if you destroy an object that's inside a collider, OnTriggerExit won't be rised too
But my solution still works ;)
Sorry but if you do instantiate a object inside a collider OnTriggerEnter does register it. But not on exit.
Answer by InvincibleCat · Jan 13, 2015 at 12:55 AM
You have multiple solutions. I will give you an easy one to understand even if it's not the best one.
Add List or turrets in your enemies script. OnTriggerEnter, you add the turret to the enemy list.
Then, OnDestroy (in your enemy script) loop on your turrets to notify that the enemy has been killed
the other solution is to have something like
public Action<EnemyScript> OnBeKilled = null;
private void OnDestroy()
{
if(OnBeDestroy != null)
{
OnBeDestroy(this);
}
}
On your EnemyScript. (Off course, replace EnemyScript by your Enemy class).
And then, in your Turret:
private void OnTriggerEnter(Collider pCollider)
{
EnemyScript enemy = pCollider.GetComponent<EnemyScript>();
enemy.OnBeKilled += OnEnemyBeKilled;
//replace with the real name of your variable
enemyCounter++;
}
private void OnTriggerExit(Collider pCollider)
{
EnemyScript enemy = pCollider.GetComponent<EnemyScript>();
enemy.OnBeKilled -= OnEnemyBeKilled;
//replace with the real name of your variable
enemyCounter--;
}
private void OnEnemyBeKilled()
{
//replace with the real name of your variable
enemyCounter--;
}
Yes i have thought of that but ins$$anonymous$$d of Add List on enemies I tried it on my turrets. But eachtime I looped the list looking for the next target it really reduced my frames. Is there a reason why? or maybe it was bad coding on my behalf?
that's why you need the list on your enemies. You only need to change something onDestroy.
With your solution, you loop on stuff each frame even if you don't need to. It your enemy that should notify the turrets
I understand what you are trying to do here. I will give it a shoot and come back.
Answer by DFortun81 · Jan 13, 2015 at 01:13 AM
You can solve this by using a semi-complicated method called Event Handlers. Essentially, you would create a simple Delegate and event handling system in your enemy's base class (if it doesn't have one, make one - these are especially useful!) and then have objects that are dependent on specific non-Unity events receive notifications when certain things happen.
public class UnitBase : MonoBehaviour
{
// Declare our delegate type. Functions that register
// with events of this type much also take a 'unit' argument.
public delegate void UnitDelegate(UnitBase unit);
// This event acts as a callback for objects that need
// to know when this unit dies and is destroyed.
public event UnitDelegate OnUnitDestroyed;
// OnDestroy is a standard MonoBehaviour function and gets
// called automatically when an object is freed from memory
// we will use this as our Invocation function.
public void OnDestroy()
{
if(OnUnitDestroyed != null) OnUnitDestroyed(this);
}
}
Then in your Turret code, you would simply register for the OnUnitDestroyed event in the code portion where you are performing counter + 1.
UnitBase unit = currentTarget.GetComponent<UnitBase>();
if(unit != null) {
// To prevent this from getting called multiple times,
// it is a good idea to Unregister immediately before
// registering when utilizing events outside of Awake.
unit.OnUnitDestroyed -= HandleOnUnitDestroyed;
unit.OnUnitDestroyed += HandleOnUnitDestroyed;
}
And then create an event handler function that does this:
private void HandleOnUnitDestroyed(UnitBase unit)
{
// The unit was destroyed, so unregister!
if(unit != null) unit.OnUnitDestroyed -= HandleOnUnitDestroyed;
--counter;
}
Then in the place where you normally decrement your counter variable, call the handle function instead:
// Substitute the word "currentTarget" with whatever object or component you
// have access to in the function you're using for this.
HandleOnUnitDestroyed(currentTarget.GetComponent<UnitBase>());
This makes it so that any class derived from "UnitBase" has its destruction event unregistered when its supposed to as well as process your decrementer.
hmmm. I have not worked with Event Handlers yet. Will have to investigate this method more.
In fact, it's almost the same solution u_u. I prefer $$anonymous$$e just because you don't need to declare any delegates. Action is no more than delegate $$anonymous$$yDelegate(T value)
Correct, InvincibleCat. I posted it a few $$anonymous$$utes after yours. I just type slower. I prefer the standard delegate/event notation since I came from a purely C# background when I started with Unity, although I suppose both methods essentially do the same thing under the hood.
To each their own.
InvinCible Cat not InvinSible Cat ^^ Yes I know it's the same. I come from pure C# too but I think it's just a personal stuff :) I used delegates a lot but then I prefer Action in some situations.
And I thought that using event is better that way:
private UnitDelegate _onUnitDestroyed = null;
public event UnitDelegate OnUnitDestroyed
{
add { _onUnitDestroyed += value; }
remove { _onUnitDestroyed -= value}
}
To prevent any subscriber using "=" and unsubscribe all the others
Your answer
![](https://koobas.hobune.stream/wayback/20220613180243im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Will Unity support morph targets built in natively? 3 Answers
Semi-Controlled Array Randomization 1 Answer
Tell if navmeshagent has reached target? 0 Answers
Making a target move when hit 3 Answers
Get list of nearby targets (JS) 1 Answer