Home > database >  Stop Null Reference Exceptions coming from Start() for Object that are still not Instantiated. Unity
Stop Null Reference Exceptions coming from Start() for Object that are still not Instantiated. Unity

Time:09-05

I have Enemy script that gets another Game Object, as target if it collides with it, in the Start() Method. The other Game Object is being Instantiated with a button and is not Active in the scene from the start. So when the Enemy spawns it tries to search for that Object but when it's not active it throws Null Reference Exceptions Error. My question is how can I check if that object is null or how to stop the error in other ways? Enemy script:

private Transform newtarget;
void Start()
{
    newtarget = GameObject.FindGameObjectWithTag("heroK").GetComponent<Transform>();
}

CodePudding user response:

Checking for NULL is straight forward, tho it probably won't help you much with this problem.

if(newTarget == null){
}

You can also work with try on a code section that is likely to fail

try{
  newtarget = GameObject.FindGameObjectWithTag("heroK").GetComponent<Transform>();
}

In this case it might be better to go about this the other way around. Have the instantiated object find all enemies and reference itself to them.

/*In start method of your spawned object script*/
Enemy scripts[]=FindObjectsOfType(typeof(Enemy));
foreach(Enemy script in scripts){
  script.SetNextTarget(this.transform);
}

/*New method in your Enemy script*/
void SetNextTarget(Transform target){
  nextTarget = target;
}

CodePudding user response:

About checking for null, there are multiple ways to express it, though they do pretty much the same:

if (GameObject.FindGameObjectWithTag("heroK") != null)
    {
        newtarget = GameObject.FindGameObjectWithTag("heroK").GetComponent<Transform>();
    }

    if (!GameObject.FindGameObjectWithTag("heroK"))
    {
        newtarget = GameObject.FindGameObjectWithTag("heroK").GetComponent<Transform>();
    }

    newtarget = GameObject.FindGameObjectWithTag("heroK")?.GetComponent<Transform>();

Be careful with setting variable first, and checking for null later, as it won't really help you:

newtarget = GameObject.FindGameObjectWithTag("heroK").GetComponent<Transform>();

// runtime will exit your method prematurely here, as you are trying to call GetComponent on a null

if (newtarget != null) {}

This could help with inactive game objects which is using FindObjectsOfType<T>(true)

But checking for null during start is one thing. You still need to set your target, so you would have to do that periodically, or when the new object is instantiated, which I don't think is really convenient.

I personally would pool (instantiate, and set inactive for future use) all the objects that you are now instantiating during runtime. This way, you could have all objects created beforehand and then set references during their initialization by passing them a list of enemies, or passing them an object that manages the enemies, if the list would be changing a lot.

CodePudding user response:

Thanks for the answers! I fixed it by calling it only when it's needed not in start() and it worked.

  • Related