CompareTag null reference

Hey,
I am using the NavMesh system (yuck) to move “units” around. (At the moment they are just capsules).
At the moment I am trying to find the closest enemy unit and set that as the “units” destination. However, for some reason, my units are getting a null reference error after using OverlapSpereNonAlloc and trying to check the tags of the objects hit.

NullReferenceException: Object reference not set to an instance of an object
UnitAttack.AcquireClosestTarget () (at Assets/Scripts/Unit/UnitAttack.cs:47)
UnitAttack.SetTarget () (at Assets/Scripts/Unit/UnitAttack.cs:26)
UnitAttack.Update () (at Assets/Scripts/Unit/UnitAttack.cs:21)

Here is my script which is attached to each “Unit”. (Yes, I know it is not the most performing, I just need it to work at this point)

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class UnitAttack : MonoBehaviour
{
    UnitAttackTypes.AttackTypes attackType;
    NavMeshAgent agent;

    float aquisitionRange = 5f;

    Collider[] hits = new Collider[50];

    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
    }

    void Update()
    {
        SetTarget();
    }

    void SetTarget()
    {
        GameObject target = AcquireClosestTarget();

        /* If AcquireClosestTarget returns null, dont continue we cant set the destination of anything */
        if (target == null) { return; }

        /* If we want to set the destination to the same point as it is already set, whats the point, wasted resources, leave */
        if (agent.destination != target.transform.position)
        {
            agent.destination = target.transform.position;
        }
    }

    GameObject AcquireClosestTarget()
    {
        /* The aim is to break out with a selected target as soon as possible. */
        GameObject target = null;
        Physics.OverlapSphereNonAlloc(transform.position, aquisitionRange, hits);
        List<GameObject> potentialTargets = new List<GameObject>();
      
        foreach (Collider hit in hits)
        {
            if (hit.gameObject.CompareTag("EnemyUnit") == true) // Error here
            {
                potentialTargets.Add(hit.gameObject);
            }
        }

        /* if there are no potential target, return already, no point in continuing */
        if (potentialTargets.Count <= 0)
        {
            return null;
        }
        /* if there is only 1 potential target, no point continuing, target it. */
        else if (potentialTargets.Count == 1)
        {
            target = potentialTargets[0];
            return target;
        }

        /* Otherwise, calculate which is the closest and make that our target. */
        foreach (GameObject potential in potentialTargets)
        {
            /* The first time we go around, we do not need to calculate anything, set it as our first target to compare against */
            if (target == null)
            {
                target = potential;
            }

            if (Vector3.Distance(transform.position, potential.transform.position) < Vector3.Distance(transform.position, target.transform.position))
            {
                target = potential;
                Debug.Log("Target Updated!");
            }
        }

        return target;
    }
}

EDIT:
And yes, I was going to use Layer Masks but then my targeting system broke so now I need to fix it first haha.

Thanks.

Thinking the hits got none and the list is full of nulls.

That is true, I forgot about that when switching to SphereOverlapNonAlloc, I will add a test for null and respond back ina few minutes.

One thing I meant to test someday, but never did was if this function clears the buffer for you. I used it once, and cleared it myself just to be sure (never tested lol). However, it does return an int. So, a) you can check for null, and/or b) you could check the return result and only loop that many times (or not at all, if 0).

I added the null check and all works fine again. I also quickly added a LayerMask so we ingnore everything thats not on an “Enemies” layer.

Nice. :slight_smile: Glad it’s all good now.