PreFab clones don't take damage and null reference error(Solved)

Hi all,

I have a issue which is know doubt very simple to solve but i have looked at so long and read loads of different things i have confused and lost sight of what is trying to be done.

#1 Prefab clones
I have a minion prefab that spawns and does everything its meant to do(seeking player and damaging the player) but when i attack with a melee auto attack none of the prefabs die which brings me to the next error…

#2 null reference

minionHP = Minion.GetComponent <MinionHealth> ();

This script is attached to the minion but is called in a attack script.
Now if i drag and drop the prefab on the scene and then load i don’t get this till the prefabs spawn and i can damage the one i dragged and dropped in the scene! FML
If i drag two prefabs into the scene i can only kill one of them and the other won’t take damage.

Attack script

private Animator anim;
    GameObject Minion;
    GameObject Wavespawner1;
    MinionHealth minionHP;
    //WaveSpawner1 waveSpawner;
    private NavMeshAgent agent;
    Transform enemy;
    private bool walking;
    private bool clickedEnemy;
    private bool isAutoatk;
    public float meleeRange = 1f;
    public float meleeAS = 0.5f;
    public int meleeDMG = 20;
    float timer;
    public LayerMask Enemies;
    void Start(){
       


    }


    // Use this for initialization
    void Awake () {
        Enemies = LayerMask.GetMask ("Enemies");
        Minion = GameObject.FindGameObjectWithTag("Enemy");
        minionHP = Minion.GetComponent <MinionHealth> ();
        //waveSpawner = Wavespawner1.GetComponent<WaveSpawner1> ();
        anim = GetComponent<Animator> ();
        agent = GetComponent<NavMeshAgent> ();


    }

    // Update is called once per frame
    void Update () {
        EnemyHit ();
        timer += Time.deltaTime;

        if (timer >= meleeAS && clickedEnemy && agent.remainingDistance <= meleeRange && minionHP.currentHealth > 0) {
            autoAttack ();
        } else {
            isAutoatk = false;
        }
        AnimationMelee ();
        //AnimationIdle ();
    }

    void FixedUpdate(){
       
        //MeleeChecker ();
        qCasting ();

    }

    void EnemyHit(){
        if (Input.GetButtonDown ("Fire2")) {
            RaycastHit hit;

            if (Physics.Raycast (Camera.main.ScreenPointToRay (Input.mousePosition), out hit, 100, Enemies)) {
                if (hit.collider.CompareTag ("Enemy")){
                    clickedEnemy = true;
                    Debug.Log ("raycast enemy hit");

                }
            }
        }
    }

    void MeleeChecker(){
        timer += Time.deltaTime;

        if (timer >= meleeAS && clickedEnemy && agent.remainingDistance <= meleeRange && minionHP.currentHealth > 0) {
            autoAttack ();
        } else {
            isAutoatk = false;
        }
    }
    /*
    public void AnimationIdle(){
        anim.SetBool ("IsIdle", idle);
    }
    */
    void AnimationMelee(){
        anim.SetBool ("IsAutoatk", isAutoatk);

    }

    void autoAttack(){
        timer = 0f;
        if (clickedEnemy && minionHP.currentHealth > 0) {
            minionHP.TakeDamage (meleeDMG);
            isAutoatk = true;
        }
    }

So my code is a bit messy but i am about 3-4 weeks into learning this so please apply patience when replying :slight_smile:

Thanks in advance!

Minion is null which means it didn’t find anything tagged as “Enemy”

So in your Awake method, you’re finding a minion with GameObject.FindGameObjectWithTag(“Enemy”). Then you’re storing that specific minion’s health in the minionHP variable.

Whenever you’re doing an attack, you’re doing damage to that same minionHP. Which means that the only minion you’re damaging is whichever minion your FindGameObjectWithTag call found in your start.

When you’ve clicked an enemy, you should store that enemy as the currently selected one:

    void EnemyHit(){
        if (Input.GetButtonDown ("Fire2")) {
            RaycastHit hit;

            if (Physics.Raycast (Camera.main.ScreenPointToRay (Input.mousePosition), out hit, 100, Enemies)) {
                if (hit.collider.CompareTag ("Enemy")){
                    clickedEnemy = true;
                    Debug.Log ("raycast enemy hit");
                    //NEW LINES:
                    Minion = hit.transform.gameObject;
                    minionHP = Minion.GetComponent<MinionHealth>();
                }
            }
        }
    }

This also means that you can remove the lines getting the Minion and the minionHP in Start - you don’t need those fields unless you’ve actually clicked an enemy.

1 Like

Baste, Thank you very much for your input that was spot on the money!!! everything now works like a dream and I’m a little annoyed at myself for getting that very wrong.

Your guidance was exactly what i was needing :slight_smile: