Storing a Gameobject from array into a Gameobject variable giving NullReferenceException
Somethinger is weird here.
transform.LookAt(choosenBoulderFish.transform.position); Gives me a NullReferenceException when I run it. If I move all the code into the same scope (or remove the if statement) it works just fine. But I dont want to continuously pick a new gameobject, I just want to do it once and use that reference. What gives man? Anybody know whats going on here. I'm suspect that arrays suck but you never know, I could be doing a dumb. HALP! FYI, the number of objects found with tag is dynamic. Increasing and decreasing as the player plays the game. So using a static number range is out.
////////
private bool pickBoulder = true;
private GameObject[] nearestBoulderFish;
private GameObject choosenBoulderFish;
void Update()
{
DoStuff();
}
void DoStuff()
{
if (pickBoulder)
{
nearestBoulderFish = GameObject.FindGameObjectsWithTag("BoulderFish");
choosenBoulderFish = nearestBoulderFish[Random.Range(0, nearestBoulderFish.Length)];
pickBoulder = false;
}
transform.LookAt(choosenBoulderFish.transform.position);
}
Are there ever no BoulderFish GameObjects in the scene at all?
Answer by ransomink · Aug 29, 2015 at 05:58 PM
Are you sure the error is on the line:
transform.LookAt(choosenBoulderFish.transform.position);
Is that your entire code or just an excerpt? I just tested this out and it worked with no errors. using UnityEngine; using System.Collections;
public class RockFish : MonoBehaviour {
private bool pickBoulder = true;
private GameObject[] nearestBoulderFish;
private GameObject choosenBoulderFish;
void Update()
{
DoStuff();
}
void DoStuff()
{
if (pickBoulder)
{
nearestBoulderFish = GameObject.FindGameObjectsWithTag("BoulderFish");
choosenBoulderFish = nearestBoulderFish[Random.Range(0, nearestBoulderFish.Length)];
pickBoulder = false;
}
transform.LookAt(choosenBoulderFish.transform.position);
}
}
But it is wiser to create a Manager GameObject inside the scene and create a script that controls the amount of fish (during gameplay), like FishManager. Inside FishManager you can have a list called fish (make it public if you want to see it update inside the inspector).
As you did, it is much easier to add each BoulderFish to the list on the FishManager script during their Awake() function since it only happens once. When the BoulderFish is destroyed, you can use a function to remove itself from the list.
This is actually a better way of doing it, not a workaround, hope this helps!
To answer your first question, it is an excerpt. Which makes me wonder if my gameObject in the transform.lookAt line was setup properly at that point. Not sure but the code is gone for now and replaced with the new stuff I explained.
Also, explaining the fishmanager makes me feel a lot better about the way I went about it. I was worried it was heavy on system resources but from what you are saying, it sounds like thats sorta the way to do things like this in the first place.
Thanks for putting my $$anonymous$$d at ease.
Yes, it is much easier. Previously, you were creating an entire array of items every time pickBoulder was true. That would be much heavier...
Answer by hexagonius · Aug 28, 2015 at 09:52 AM
same guess here. do a null check on chosenbolderfish. if null debug.not something do you know. otherwise lookat it.
Answer by SpaceManDan · Aug 28, 2015 at 10:14 AM
No, there is always at least one. I did try a != null statement just to make sure something wonky wasn't going on.
I managed to figure out how to work around it.
Had to create a class on an empty gameobject that stores a list of gameobjects. The list removes and adds as necessary.
I.E.
public List boulderFishes;
then inside the BoulderFish Class I added this on Awake()
GameObject gameController = GameObject.Find("GameController"); gameController.GetComponent().boulderFishes.Add(this.transform.parent.gameObject);
That populates the boulderFishes list with the current boulder fish.
THENNNNnnnn. I put
choosenBoulderFish = gameController.GetComponent().boulderFishes[Random.Range(0, gameController.GetComponent().boulderFishes.Count)];
thisRockFish.transform.LookAt(choosenBoulderFish.transform.position);
on the rockfish class that was originally mentioned in my question at the beggining of this post.
SOOOoo in short. I had to create a list on a separate game object that stores what I need and reference the class on that gameobject for the info I need at the time I need it.
Workaround = yes, resource heavy compared to array = yes.
If anybody can figure out a better way I'd like to hear it.