Simple AOE damage script won't work

i’m new to scripting
i just want to add simple cooldown based AOE damage
basically it will hit every “Enemies” tagged gameobjects inside my player SphereCollider radius

to modify current game that i mimic unity’s tutorial survival shooter
forget about the animation and audio i’ll add it later but these simple script simply won’t work

the damage won’t applies and after i pressed play says this error
nullreferenceexception on my enemyHealth (line:17)get component

i know it causes bcs the script doesn’t know which EnemyHealth i’m referring to

but other script works fine to call other game object’s script and function
also i’ve already tried to public Enemyhealth enemyHealth and drag the prefabs to my script inspector
the damage still won’t apply

fyi my enemies game objects are not in the scene its will spawn after sometimes like in the tutorial
so i thought its because of that so i tried to move enemyHealthgetcomp to update func but still got the same error

here’s the code

using UnityEngine;
using System.Collections;

public class AoeSlash : MonoBehaviour {

    public float cooldownAoe = 20f;
    public int aoeDamage = 100;

    GameObject enemies;
    EnemyHealth enemyHealth;
    bool enemiesInRange;
    float cooldowntimer;
  
    void Awake ()
    {
        enemies = GameObject.FindGameObjectWithTag ("Enemies");
        enemyHealth = enemies.GetComponent <EnemyHealth>();
    }
  
    void OnTriggerEnter (Collider other)
    {
        if(other.CompareTag ("Enemies"))
        {
            enemiesInRange = true;
        }
    }
  
    void OnTriggerExit (Collider other)
    {
        if(other.CompareTag ("Enemies"))
        {
            enemiesInRange = false;
        }
    }
  
  
    void Update ()
    {
        cooldowntimer += Time.deltaTime;
        if (Input.GetButton ("Fire2") && cooldowntimer >= cooldownAoe)
        {
            aoeAttack();
        }
    }
  
    void aoeAttack ()
    {
        cooldowntimer = 0f;
        if (enemyHealth.currentHealth > 0 && enemiesInRange)
        {
            enemyHealth.AoeDamaged (aoeDamage);
//AoeDamaged is a function from my EnemyHealth script which only contain (int dmg) currenthealth -= dmg;
//because main TakeDamage func contains vector3 so i had to make another new AoeDamaged func
        }
    }
}
  • if possible can somebody give me better script example for the aoeAttack func that gives default raycasthit.point number(undependant to pointer) so i don’t have to make 2 TakeDamage(the one w/ vector3) func on EnemyHealth script
    , because the main attack using raycasthit

thanks before

The nullref error you are getting is because of this. The Awake function is called immediately at the start, and since your objects aren’t there, it’s blanking out.

Side note: You have your range bool spelled wrong in your OnTriggerExit.

I’m no efficiency expert, so I don’t know what the optimal approach is, but you could simply make your “enemies” a blank list and in your OTEnter method append other.gameobject to the list(and/or do that for the enemyHealth scripts) and do a for loop on your list in your attack method, etc. Then delete them from the list as they exit the trigger.

Catch with that approach being that you have to be careful how you remove list objects as it can quickly mess up your for loops if things start disappearing at the wrong times. If taking a forward approach like that, I’d use a dictionary rather than separated lists/variables for your Bool, objects, scripts.

That’s just a simple quick-fix though. As I understand it, repeatedly calling Find and GetComponent and stuff isn’t optimal, so you could probably find a better way through it.

Someone more experienced with code efficiency can probably pop in here and give a more elegant approach.

yeah the OTExit range was only typo in this thread
oh thanks a lot! swap the EHgetcomp to the OTEnter func it fixes the nullreference, no more error.
eventho now its applying the damage exactly to the current enemy health
yet its still doesn’t work exactly as intended its only damage 1 enemy whenever “Enemies” enter my collider
firstly i thought it damage whoever first enter the collider
but after sometimes i noticed that whoever enter the scene first it will lock on to that enemy
eventho he’s not inside the collider as long there’s “Enemies” tagged game object inside my collider it let me
damage that locked enemy

It’s because of the way your Enemies variable is a GameObject. You should make this either a list or a dictionary of some type that way it can keep track of more than one enemy.

Then you could loop through that in your aoeAttack method and damage each of them in the list that are in range and healthy.

To remove them from your list/dict you could do an extra if statement that removes that entry from your Dict., etc., if their currentHealth <= 0. Removing them only when they are dead would keep you from having to constantly add/remove entries everytime they enter/exit the Trigger.

I would have a dictionary that had 3 entries - 1. the gameobject 2. the in range Bool 3. the EH script.
When something enters the trigger, have an if check to see if it’s in the dictionary already, if it is, simply make the Bool True like you have it. If it’s not, add it to the Dict and do a GCScript and get that in there.

Then you can just look through the dictionary at their range Bools and damage the ones that are True or whatever.

When they leave the collider you set that range bool back to False in the Dict.

I haven’t done much programming in quite a while, so I’m not typing out any code atm, but that’s the basic concept you could try.