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.
This is my Reticle Setup:
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);
}