C# - foreach problem

The problem is that I’m creating here an array of Colliders, to get acces to script “Enemy” attached to them and execute function which slow object. After I save all colliders in class variable resetCol. Then I wait for 1.2f and want to reset speed of each object inside this array.
So problem is, that when some object is destroyed before executing last part of this code (under “yield return new WaitForSeconds(1.2f);”) - unity show me an error. As - there is no reference “NullReferenceException” and it’s ok, because in array appears empty space. So Idk how to fix it, because inside foreach I’m checking for “collider != null”, so it shouldn’t take empty space inside array, isn’t it?

So, basically, the problem is - am I checking empty statement inside array wrongly?

I probably misspoke something (have not good enough English knowledge), so ask - I’ll try to explain.

Collider[] resetCol;
public float duration;
public float slowerSlow;

IEnumerator GrowingSphere()
    {
        float r = 0;
        float distance = 0;
        while (r < duration)
        {
            Collider[] colliders = Physics.OverlapSphere(transform.position, distance);
            r++;
            distance += .074f;
            foreach (Collider collider in colliders)
            {
                if (collider.tag == "Enemy")
                {
                    collider.GetComponent<Enemy>().Slow(slowerSlow);
                }
            }
            yield return new WaitForFixedUpdate();
            resetCol = colliders;
        }
        yield return new WaitForSeconds(1.2f);
        foreach (Collider collider in resetCol)
        {
            if (collider != null)
            {
                collider.GetComponent<Enemy>().speed = collider.GetComponent<Enemy>().startSpeed;
            }
        }
    }

@ADiSiN in your first foreach statement you selectively call collider.GetComponent<Enemy>().Slow(slowerSlow); to those colliders tagged “Enemy”. If you have found the need to do that, it means that you suspect, or may have found, that the the OverlapSphere method returns some other colliders that are not tagged “Enemy”.

And apparently, this is why your getting the NullReferenceException, not because the code inside the second foreach tries to execute a statement when there’s no collider, but because a collider instance does not have an Enemy Component. So, collider.GetComponent<Enemy>() returns null, and your are trying to set the speed of null to the startSpeed of null.

So, the solution is what @PizzaPie suggested, i.e. to check if the collider has an Enemy component:

if (collider != null && collider.GetComponent<Enemy>() != null)

You need to decouple when the decision to do something is made from when it actually happens. That’s a command pattern type problem.

I would use something like Invoke to make the speed be reset after 1.2 seconds. I believe that scheduled invoke’s aren’t executed if an object was destroyed in the intervening time. For instance, you could modify Enemy to have a method like SetSpeedAfterDelay that uses invoke to defer setting.

That assumes that you have access to the Enemy script. If not, you’d have to do a little more work.

In any event, I would get rid of the second foreach altogether and just schedule a command in the initial foreach.

On which line is the null reference exception? That’ll tell us what variable to look for. It seems resetCol could be null because you say the array is empty. This is because resetCol must have the same length as colliders, if it doesn’t, then not all or any of the collided game objects will copy to the array. You have to set the length of the array first then copy it over

resetCol = new Collider[ colliders.Length ];
resetCol = colliders;

Also, use if (collider.CompareTag( "Enemy" ) ) instead of .tag. It is much more efficient…