0
\$\begingroup\$

I could really use another set of eyes on this. I am running into this error: NullReferenceException: Object reference not set to an instance of an object I can't figure out.

In the script below. I've verified I'm cycling through the children well enough, and I thought I assigned them an appropriate object but for some reason only the first child of the selected reticle is turning red, and the following children are throwing the errors.

enter image description here

This is my Reticle Setup:

enter image description here

Each reticle group has a various number of objects with an Image component that make up a reticle. I turn on and off each reticle group depending on what fire button is being pressed, and return to default if none are pressed. On top of that the reticles are Red or White depending on if the WeaponManager says its a valid target or not.

These two lines in the script below are throwing the errors.

childGameObject2.GetComponent<Image>().color = Color.white;
childGameObject1.GetComponent<Image>().color = Color.red;

Whole reticle script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class reticle : MonoBehaviour
{

    [SerializeField] private GameObject defaultReticle;
    [SerializeField] private GameObject machineGunReticle;
    [SerializeField] private GameObject rocketLauncherReticle;

    private int reticleSelect;
    private int fireOneSelect;
    private int fireTwoSelect;
    private int utilitySelect;

    private Transform childGameObject1;
    private Transform childGameObject2;

    // Start is called before the first frame update
    void Start()
    {
        // remove mouse cursor
        Cursor.lockState = CursorLockMode.Locked;
        Cursor.visible = false;

        defaultReticle.SetActive(true);
        reticleSelect = 1;

    }

    // Update is called once per frame
    void Update()
    {
        // update weapon selections from WeaponManager.cs
        fireOneSelect = WeaponManager.fireOneSelect;
        fireTwoSelect = WeaponManager.fireTwoSelect;
        utilitySelect = WeaponManager.utilitySelect;

        // toggle locked and free aim
        if (Input.GetKey(KeyCode.Tab))
        {
            if (Cursor.lockState == CursorLockMode.Locked)
            {
                Cursor.lockState = CursorLockMode.Confined;
            }
            else
            {
                Cursor.lockState = CursorLockMode.Locked;
            }
        }

        if (Input.GetKeyDown(KeyCode.Escape))
        {
            Cursor.visible = true;
        }

        if (WeaponManager.eligibleTarget == false)
        {
            // handle out of range reticle color changes
            for (int i = 0; i < gameObject.transform.childCount; i++)
            {
                if (gameObject.transform.GetChild(i).gameObject.activeSelf == true)
                {
                    Debug.Log(gameObject.transform.GetChild(i).name);
                    // cycle through all reticle children and turn them red
                    for (int g = 0; g < gameObject.transform.GetChild(i).gameObject.transform.childCount; g++)
                    {
                        childGameObject1 = gameObject.transform.GetChild(i).gameObject.transform.GetChild(g);
                        Debug.Log(childGameObject1.name);
                        //LINE BELOW CAUSING ISSUE WHEN NOT ELIGIBLE TARGET
                        childGameObject1.GetComponent<Image>().color = Color.red;
                    }
                }
            }
        }
        else if (WeaponManager.eligibleTarget == true)
        {
            // handle out of range reticle color changes
            for (int m = 0; m < gameObject.transform.childCount; m++)
            {
                if (gameObject.transform.GetChild(m).gameObject.activeSelf == true)
                {
                    Debug.Log(gameObject.transform.GetChild(m).name);
                    // cycle through all reticle children and turn them red
                    for (int h = 0; h < gameObject.transform.GetChild(m).gameObject.transform.childCount; h++)
                    {
                        childGameObject2 = gameObject.transform.GetChild(m).gameObject.transform.GetChild(h);
                        Debug.Log(childGameObject2.name);
                        //LINE BELOW CAUSING ISSUE WHEN ELIGIBLE TARGET
                        childGameObject2.GetComponent<Image>().color = Color.white; 
                    }
                }
            }
        }

        // decide if firing reticle is needed or show default reticle
        // reticleSelect values  
        // 1 = default
        // 2 = fireOne
        // 3 = fireTwo
        // 4 = utility
        if (Input.GetButton("Fire1"))
        {
            reticleSelect = 2;
        }
        else if (Input.GetButton("Fire2"))
        {
            reticleSelect = 3;
        }
        else
        {
            reticleSelect = 1;
        }

        // reset reticles to inactive to simplify code below
        for (int k = 0; k < gameObject.transform.childCount; k++)
        {
            gameObject.transform.GetChild(k).gameObject.SetActive(false);
        }

        // handle reticle switch logic
        if (reticleSelect == 1)
        {
            // handle default reticle
            defaultReticle.SetActive(true);
        }
        else if (reticleSelect == 2)
        {
            // handle fire one reticles
            switch (fireOneSelect)
            {
                // 1 = machineGun
                // 2 = na
                // 3 = na
                case 1:
                    machineGunReticle.SetActive(true);
                    break;
                case 2:
                    //newReticle.SetActive(true);
                    break;
                case 3:
                    //newReticle.SetActive(true);
                    break;
                default:
                    defaultReticle.SetActive(true);
                    break;
            }
        }
        else if (reticleSelect == 3)
        {
            // handle fire two reticles
            switch (fireTwoSelect)
            {
                // 1 = rocketLauncher
                // 2 = grenadeLauncher
                // 3 = na
                case 1:
                    rocketLauncherReticle.SetActive(true);
                    break;
                case 2:
                    //grenadeLauncher.SetActive(true);
                    break;
                case 3:
                    //newReticle.SetActive(true);
                    break;
                default:
                    defaultReticle.SetActive(true);
                    break;
            }

        }
        transform.position = Input.mousePosition;
    }

}

On a separate note, this bit of code seems incredibly inefficient to turn off all reticles each update before activating the chosen one, but its a lot cleaner than adding all the inactivate lines in the switch statement below that. How would one go about turning them on and off with less code?

// reset reticles to inactive to simplify code below
for (int k = 0; k < gameObject.transform.childCount; k++)
{
   gameObject.transform.GetChild(k).gameObject.SetActive(false);
}
\$\endgroup\$
1
\$\begingroup\$

Are you sure that Left Marker has an Image component? Double check it, looks like it is the only game object that is problematic.

As for the for loop it looks like you could remove the code after the loop and replace it with something that would immediately switch between active and inactive based on the reticleSelect value (just make sure the indexes match when you set reticleSelect).

// activate or deactivate reticles based on user input
for (int k = 0; k < gameObject.transform.childCount; k++)
{
   gameObject.transform.GetChild(k).gameObject.SetActive(k == reticleSelect);
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.