NullReferenceException: Object reference not set to an instance of an object

Hello. I have an error that started appearing right after I referenced the animator conditions in the code. If I remove the lines of code referencing the animator, the game works fine and it Debog.Log whenever the there is an enemy in lane and whenever there isnt one, correctly; but as soon as I add the animator lines of code it doesn’t work. Should the position of the parent defenders be the same as the “attacker spawners” or should the body of the defenders be the ones the same as the “attacker spawners” .Thanks.

Errors are:
NullReferenceException: Object reference not set to an instance of an object
Shooter.Start () (at Assets/Scripts/Shooter.cs:15)
NullReferenceException: Object reference not set to an instance of an object
Shooter.Update () (at Assets/Scripts/Shooter.cs:23)
NullReferenceException: Object reference not set to an instance of an object
Shooter.Update () (at Assets/Scripts/Shooter.cs:29)

public class Shooter : MonoBehaviour
{
[SerializeField] GameObject projectilePrefab, gun; // when you make the type of the variable “GameObject”, you can drag any gameObject in there, which why it is better to make the type of the variable of the GameObject the Script/Class thats on that gameObject that we are dragging into the [serializefield] is the unity interface.
// instead of adding another line of code for “gun” ([SerializeField] GameObject gun;), we can just add a comma after the “projectilePrefab” and add the “gun” there which adds two seperate variables since they are both of the same type.
Spawner myLaneSpawner;
Animator animator;

private void Start()
{
    SetLaneSpawner();
    animator.GetComponent<Animator>();

}
private void Update()
{
    if (IsAttackerInLane())
    {
        // TODO: Change animation state to shooting
        animator.SetBool("isAttacking", true);
        Debug.Log("Shoot");
    }
    else
    {
        // TODO: Change animation state to idle
        animator.SetBool("isAttacking", false);
        Debug.Log("Sit and Wait");
    }
}

private void fire()
{
    Instantiate(projectilePrefab, gun.transform.position, Quaternion.identity);
}


// Create an array to store each of the Attacker Spawners
private void SetLaneSpawner() // ***MMMMMM*** Gets the spawner's GameObject location in relation to the spawned defender (that we placed) location.
{
    //Create a variable that holds an array of all the spawners that we have in the level.
    Spawner[] spawners = FindObjectsOfType<Spawner>();

    foreach (Spawner spawner in spawners)
    {
        // A bool that returns true if the shooter(defender that shoots) is in the same lane as the spawner GameObject (which we referenced/found using the "FindObjectsOfType<Spawner>()".
        // isCloseEnough = (Each spawner's y position (getting each by using the "foreach" loop) - the y position of the gameObject that this script/class is attached to (defender that shoots) <= 0 or tinniest fraction close to 0 (using "Mathf.Epsilon" because there might be a tiny tiny fraction that is more than 0).
        // Need to use "Maths.abs" to prevent us from having a negative value, which will be smaller than 0 or "Mathf.Epsilon" and return true. 
        bool isCloseEnough = (Mathf.Abs(spawner.transform.position.y - transform.position.y) <= Mathf.Epsilon);

        if (isCloseEnough) // if equals to true
        {
            // then the "myLaneSpawner" (variable referencing the spawner script/class) is EQUAL to the "spawner" that we just looped through in our "foreach" (which) we found using "FindObjectsOfType<Spawner>();" in the array;
            myLaneSpawner = spawner;
        }
    }
}


// Create a mechanism to shoot or not shoot based upon whether we have an attacker in our lane.
private bool IsAttackerInLane() // Checks if there is an attacker in our lane (by checking if the "spawner" gameobjects have any children, which is where the enemyPrefabs are placed under depending on which "spawner" gameObject instantiated them)
{
    // if my lane spawner child count is less than or equal to 0
        // return false
    if (myLaneSpawner.transform.childCount <= 0)
    {
        return false; 
    }
    else
    {  
        return true;

    }
}

}

Hi,

NullReferenceException means that a reference (“link”) to an instance is missing. Double click on the error message to see to which line in your code it is referring. If you exposed a field in the Inspector, make sure that it’s not empty.

There is a variable in your IsAttackerInLane method: myLaneSpawner.

Check where a lane gets assigned to this variable. The y-coordinates of both the defender and the spawner must be equal. Otherwise, the condition gets evaluated to false, and nothing gets assigned to myLaneSpawner. If the variable is empty, it is null, thus the NullReferenceException.

Did this help?


See also:

Hello,

Thank you for your response. I think I figured what the problem is, the defenders’ positions when they spawn, are not rounded. I recreated the canvas with Rick’s specifications but it didn’t solve the problem. I also resetted the defenders and attackers parents positions to 0, but moved their children to make them appear in the right spot, but still didn’t fix the problem, the defenders dont snap to whole number vectors. Thanks.


This is the lizard’s position when it spawns. The Y position shown is the one set the child. The parent’s transform is all set to zero.


This is the cactus’s position when it spawns. Same as the lizard. The Y position shown is the one set the child. The parent’s transform is all set to zero.

The little offset is not necessarily a problem.

Cactus (Clone) is the parent. The parent is supposed to have a rounded position due to our code. The child may have an offset, so you can easily adjust the position of the sprite.

Does the parent have a Rigidbody2D attached? If not, move the collider to the parent game object. Otherwise, no collision will be detected.

Hello,

Sorry to bother you again. So the every prefab (attacker and defenders) have a RigidBody 2D and a collider2D.

I noticed that when the lizards are spawned their Y positions are all zero, which I know shouldnt matter because of the " newAttacker.transform.parent = transform;" in the AttackerSpawner script, but I dont know what else might be causing the problem. All the prefab parents’ positions are set to 0. They have a collider2D and a RigidBody2d. And the spawner gameObjects’ Y position values are all whole numbers. Thanks.

When interpreting the position values in the Inspector, we need to bear in mind that the values are relative to the parent position.

In the second screenshot, the Lizard is not at y = 0 (global position). Since the parent appears to be spawned on a grid line, I think the position is indeed rounded. And the spawner and the defender are on the same line, so the screenshot looks fine so far.

If the offset of the child (Body) bothers you, move the Lizard in the first screenshot a bit to the left until it fits the square. Then apply the changes to the prefab.

Okay. Thank you. I found what was causing the error. Turns out when I was referencing the animator in the shooter script in the Start method, I had it “animator.GetComponent();” insead of “animator = GetComponent();” and I just noticed it today.

Good grief! Now that you mentioned it, the problem is obvious. :no_mouth:

I’m glad you spotted the typo and fixed it. However, I’m slightly surprised why you didn’t get any NullReferenceException errors. They would have helped to find the root of the problem faster.

There was NullReferenceException errors but I commented them out because they were pausing the game every time. But when I double clicked the NullReferenceException errors before commenting them out, they didn’t highlight the typo line (which was the reference), instead they highlighted the other “animator.SetBool(“isAttacking”, true)” lines which had no issues.

The error message referred to animator.SetBool(“isAttacking”, true); because in this line, the program tries to access a non-existing object via the animator variable. When you get a NullReferenceException in a line like this, all you have to do is to check where the object is supposed to get assigned to the variable, if it got assigned during runtime and, if it did, where and why the variable loses the reference to the object. At some point, you would have checked the line with GetComponent.

animator.GetComponent(); is valid code, hence you didn’t get any error in that line.

I hope this made sense.

Have a nice weekend! :slight_smile:

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms