What is the best way to clear an array of Components?

I created an array to store all cameras in the scene as

var cameras : Camera[];

function Start() {
     cameras = GameObject.FindObjectsOfType(Camera) as Camera[];
}

I’d like to clear the content of cameras. One way I can think of is;

function ClearCameras(cams : Camera[]) {
     for(var c : Camera in cams) {
          c = null;
     }
}

Is there a shorter way of doing this? Just imagine, having arrays that contain cameras, car, etc, would require significant amount of repetition of code.


EDIT

See replies of @vexe and @fafase below. Take the important note below about passing target array (to be cleared) into an extension method, DO NOT use ref. I did not want to return a new array out of the extension method.

2 Answers

2

If you were using a list you could do list.Clear(); - If it’s just a regular array, just null the whole thing: cameras = null; as long as you don’t have other references to the array, it will get garbage collected. Or just new it up again: cameras = new Camera; - (In C++, if you do cameras = null; that will be a memory leak since there’s no garbage collection, so you have to go over each element and free it)

+1 Correct - He should clarify a bit more. If it was an array of ints, strings, floats and anything that's not instantiate-able in the scene it will get collected and array = null; is enough - but if it was an array of Objects (cameras, rigidbodies, gameObjects, etc) - he should worry about Destroying them as well.

Ah! I was under impression that nulling (every)things would tell the GC to get rid of them (destroy). Certainly I was wrong. Thanks for the insight @vexe.

There is no shorter way to perform your action. You could though create an extension method so that it is done in one line:

public static class Utility{
   public static Object[] ClearArray(this Object[] array){
       foreach(Object obj in array)
       {
           if(obj != null)
               Destroy(obj);
       }
       return null;
   }
}

then use:

cameras = cameras.ClearArray();

Note: you have to do this little trick above of assigning into the array because you cannot use extension method with a reference of the object.

Hmm, Camera is not a GameObject - Camera is a Behaviour which is a Component which is a Object. Since both GameObject and Component ultimately inherits Object I think it makes sense to make the extension for UnityEngine.Object[] instead of GameObject[]

"Note: you have to do this little trick above of assigning into the array because you cannot use extension method with a reference of the object." - Could you clarify what you meant with that line a little bit? - did you mean I can't do: myRef.myExt();?

Indeed the Camera is a component but you would just have to change the type, this was more generic example. I changed it to Object. As for trick explanation you cannot do: public static GameObject[] ClearArray(ref this GameObject[] array); What you are getting inside the methods is a copy of the reference to the array so modifying 'array' does not affect the actual array outside, just the copy of the pointer inside the method.

Right. @ikelaiah if that sounded confusing for you, take a look at [this][1]. An eye opener by Jon Skeet :) [1]: http://www.yoda.arachsys.com/csharp/parameters.html

@fafase, @vexe Thanks for the info. I got it.