My player character has is a trigger and uses the below code to detect enemies
protected void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.CompareTag(“Enemy”))
{
enemyInRange = true;
collision.gameObject.GetComponent().DepleteHealth(1);
}
}
This works fine when I move my player over the enemy multiple times it take 1 point of damage off them which is fine.
But what I want is to only call that DepleteHealth() method when the player presses the E key instead. I tried to do it inside the update method but only works on one enemy, when you move your player over to enemy number 2 you get an error saying that the referenced object was destroyed which is correct because Enemy 1 was, my code cant register that the player is in front on Enemy 2 now.
I cant figure out how to kill enemy 1 then kill enemy 2 when I press the E key.
I reproduced your problem. I created Player object with the Player script and a couple of enemies with the EnemyHealth script attached to each of them. Player script contains the list of enemies that are currently within the range of the collider. The list is static because each enemy has to remove itself from the list when destroyed. That takes into consideration the case when the enemy would be destroyed not by pressing E key, but somehow else. Hope that helps.
Player script:
public class Player : MonoBehaviour
{
public int damage = 1;
public static List<EnemyHealth> enemiesInRange = new List<EnemyHealth>();
void Update()
{
if (Input.GetKeyDown(KeyCode.E))
for(int i = enemiesInRange.Count - 1; i >= 0; i--)
enemiesInRange*.Deplete(damage);*
-
}*
-
void OnTriggerEnter2D(Collider2D collision)*
-
{*
-
if (collision.gameObject.CompareTag("Enemy"))*
-
{*
-
var enemyHealth = collision.GetComponent<EnemyHealth>();*
-
if (enemyHealth!=null && !enemiesInRange.Contains(enemyHealth))*
-
enemiesInRange.Add(enemyHealth);*
-
}*
-
}*
-
void OnTriggerExit2D(Collider2D collision)*
-
{*
-
if (collision.gameObject.CompareTag("Enemy"))*
-
{*
-
var enemyHealth = collision.GetComponent<EnemyHealth>();*
-
if (enemyHealth!=null && enemiesInRange.Contains(enemyHealth))*
-
enemiesInRange.Remove(enemyHealth);*
-
} *
-
}*
}
EnemyHealth script:
public class EnemyHealth : MonoBehaviour
{
-
public int health;*
-
int maxHealth = 3;*
-
void Awake()*
-
{*
-
health = maxHealth;*
-
}*
-
public void Deplete(int damage)*
-
{*
-
health -= damage;*
-
if (health <= 0)*
-
Destroy(gameObject);*
-
}*
-
void OnDestroy()*
-
{*
-
if (Player.enemiesInRange.Contains(this))*
-
Player.enemiesInRange.Remove(this);*
-
}*
}
A bit of a silly question, but I know I’ve made this mistake before: are both/all of your enemies marked with the tag “Enemy”? The other thing I would consider is using the method OnTriggerStay2D which checks continually while the trigger is active. So:
private void OnTriggerStay2D(Collider2D collider)
{
if (collider.tag == "Enemy")
{
//Your damage function
}
}
What I also may suggest is switching it around. What I mean is give the enemy objects a trigger box collider and run the collider check from the enemy checking if the Player is in the collider instead of checking if the Enemy is in the Player’s collider (which is what I think you’re doing given that you’re checking for tag “Enemy”??)
Hello
Thanks for the response.
Yes both are tagged with Enemy.
I have tried switching around already but no good.
You cant call Input.GetKeyDown inside OnTriggerStay or Enter, must be called in the Update() method.
This should seem easy in theory but I cant wrap my head around what the solution might be.
Once I kill enemy 1 Unity still thinks I am trying to kill enemy 1 when I am trying to kill enemy 2.
This code below works perfectly when I touch my player off both enemies one after another, but I need to alter it to only kill when I press the E key.
You should do a raycast in the Update() to see which enemy you’re closest to, by getting the distance from each enemy to the player and sorting it. This could be done every time you press the ‘E’ key, and if the distance between an enemy and the player is very small, you’re colliding. @TheIrishKraken