0

I'm having an odd encounter with a NullReferenceException. I'm relatively new to coding so the answer might be really simple. I'm fully aware that the computer is probably right, but I don't know why this error is being thrown.

Basically, I'm trying to filter out non-player GameObjects from an array and write those to a new array, but whenever it writes to a new array, it throws a NullReferenceException.

I've checked if the object I'm trying to write to the array is null and I don't think it should be - based on that it successfully logs the name of the object to the console.

This is the error Unity is giving me:

NullReferenceException: Object reference not set to an instance of an object EnemyAI.DetectPlayersInRange () (at Assets/Scripts/EnemyAI.cs:137) EnemyAI.FixedUpdate () (at Assets/Scripts/EnemyAI.cs:63)

and the lines of code are:

playerLocationsInRange[players] = collider.gameObject.transform; (Line 137)

DetectPlayersInRange(); (Line 63, calls the function where the error originates)

.

Here's the block of code:

    {
        Collider2D[] objectsInRange = Physics2D.OverlapCircleAll(rb.position, viewDistance);
        int players = 0;

        foreach (Collider2D collider in objectsInRange)
        {
            if (collider != null)
                if (collider.gameObject != this.gameObject && collider.TryGetComponent<Player>(out Player player))
                {
                    Debug.Log(collider.name);
                    playerLocationsInRange[players] = collider.gameObject.transform;
                    players++;
                }
        }
    }

and this is the full file, if anyone needs it:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Pathfinding;

public class EnemyAI : MonoBehaviour
{
    public GunRotation gunRotation;
    public GunVFX gunVFX;

    public Transform target;

    public float nextWaypointDistance = 3f;

    Path path;
    int currentWaypoint = 0;
    bool reachedEndOfPath = false;

    Seeker seeker;
    Rigidbody2D rb;

    float storedTime = -0.2f;

    string UPDATE_PATH_METHOD_NAME = "UpdatePath";


    public float viewDistance = 5f;
    [SerializeField] private LayerMask playerLayer;
    [SerializeField] private ContactFilter2D filter;

    private Transform[] playerLocationsInRange;
    private Transform[] accessiblePlayers = null;

    // Start is called before the first frame update
    void Start()
    {
        seeker = GetComponent<Seeker>();
        rb = GetComponent<Rigidbody2D>();

        InvokeRepeating(UPDATE_PATH_METHOD_NAME, 0f, 0.5f);
    }

    void UpdatePath()
    {
        seeker.StartPath(rb.position, target.position, OnPathComplete);
    }

    void OnPathComplete(Path p)
    {
        if (!p.error)
        {
            path = p;
            currentWaypoint = 0;
        }
    }

    // Update is called once per frame
    void FixedUpdate()
    {
        Vector2 rayDirection = (rb.position - (Vector2)target.position).normalized;
        Debug.DrawRay(rb.position, rayDirection, Color.green);

        DetectPlayersInRange();

        if (playerLocationsInRange != null)
            if (playerLocationsInRange.Length > 0)
            {
                DetectObstacles();

                if (accessiblePlayers != null)
                    if (accessiblePlayers.Length > 0)
                    {
                        ShootAtPlayer();
                        return;
                    }
            }

        Movement();
    }

    void Movement()
    {
        if (path == null)
            return;

        // Does not continue if waypoint reached
        if (currentWaypoint >= path.vectorPath.Count)
        {
            reachedEndOfPath = true;
            return;
        }
        else
        {
            reachedEndOfPath = false;
        }

        // Get direction
        Vector2 direction = ((Vector2)path.vectorPath[currentWaypoint] - rb.position).normalized;
        Vector2 force = direction * 5;

        // Move
        if (Time.time - storedTime >= 0.2f)
        {
            rb.AddForce(force, ForceMode2D.Impulse);

            gunRotation.updateGraphics(-direction);

            gunRotation.shoot();
            gunVFX.explosion();

            storedTime = Time.time;
        }

        // If reached current waypoint, move on to next
        float distance = Vector2.Distance(rb.position, path.vectorPath[currentWaypoint]);

        if (distance < nextWaypointDistance)
        {
            currentWaypoint++;
        }
    }

    // Detect all players in range and add them to array
    void DetectPlayersInRange()
    {
        Collider2D[] objectsInRange = Physics2D.OverlapCircleAll(rb.position, viewDistance);
        int players = 0;

        // Filter out non-player Colliders
        foreach (Collider2D collider in objectsInRange)
        {
            if (collider != null)
                if (collider.gameObject != this.gameObject && collider.gameObject.TryGetComponent<Player>(out Player player))
                {
                    Debug.Log(collider.name);
                    playerLocationsInRange[players] = collider.gameObject.transform;
                    players++;
                }
        }
    }

    // Eliminate players based on accessibility
    void DetectObstacles()
    {
        int players = 0;

        foreach (Transform player in playerLocationsInRange)
        {
            RaycastHit2D hit;
            Vector2 direction = (rb.position - (Vector2)player.position).normalized;

            if (!Physics2D.Raycast(rb.position, direction, Vector2.Distance(rb.position, player.position), playerLayer))
            {
                accessiblePlayers[players] = player;
            }
        }
    }

    // Shoot
    void ShootAtPlayer()
    {
        // Get direction
        Vector2 direction = ((Vector2)path.vectorPath[currentWaypoint] - rb.position).normalized;
        Vector2 force = -direction * 5;

        // Move
        if (Time.time - storedTime >= 0.2f)
        {
            rb.AddForce(force, ForceMode2D.Impulse);

            gunRotation.updateGraphics(direction);

            gunRotation.shoot();
            gunVFX.explosion();

            storedTime = Time.time;
        }
    }
}

I'm not sure what other information is necessary, so just tell me if I'm missing something that'd be helpful to resolve this.

Solutions are appreciated, or if somebody could even just point me in the right direction.

0 Answers0