Code optimisation - how to use arrays?

Hello!

So I have made a starfield, loaded procedurally by simply instantiating a star in a random position when the scene loads.

To make the starfield infinite, I added a script to each individual star prefab. The code says if it gets too far away from the camera on either the X or Y axis, move it to the other side of the camera. This works pretty well to create an infinite starfield.

	if (transform.position.y < cam.transform.position.y-7)
	{
		transform.position.y = transform.position.y+14;
	}
	
	if (transform.position.y > cam.transform.position.y+7)
	{
		transform.position.y = transform.position.y-14;
	}
	
	if (transform.position.x < cam.transform.position.x-12)
	{
		transform.position.x = transform.position.x+24;
	}
	
	if (transform.position.x > cam.transform.position.x+12)
	{
		transform.position.x = transform.position.x-24;
	}

The problem is that it clearly isn’t very efficient having this code running on 700 seperate objects. I have been looking into controlling all the objects from one script, probably using arrays, but I can’t find a way to apply logic to all GameObjects inside an array. How would I do this? I can apply it to a single object in the array by using something along the lines of “myArray [1].transform.position”, but not how to do it for every object in the array. Thank you!

Hi, I would go for particle: Unity - Scripting API: ParticleSystem

You can have billboards or 3d objects to represent the stars and you have access to each particle position individually using GetParticles (Unity - Scripting API: ParticleSystem.GetParticles) and SetParticles().

You would then have 1 object that iterates with a for loop through each particle to change it’s position where you want it (with setting the life of particles to infinite or a very big value first).

I would also recommend to cache the bounds of the camera in local variables, like float myXLimit = camera.transform.position.x and comparing against myXLimit (accessing transfom can become expensive in a loop like that)

One way is not to use the array but more likely to use the engine to perform the check for you.

Place a trigger box on the outside and when the object enters it then, send it on the other side. This goes on the box:

void OnTriggerEnter(Collider col){
   if(col.gameObject.tag == "Star")// This can be removed if only stars get there
      // reposition the star
}

The engine is optimized using any kind of algorithm to skip check if the object is not meant to be close to the trigger box. So I would recommend it.

Otherwise, your code is not too much of a big deal, it is just some basic arithemetics done in a few clicks, I would not bother doing some micro optimization, even for thousands of objects. You could do a check up front to skip the four next checks.

if((tansform.position - cam.position).sqrMagnitude > range) return;

then if the distance is not great enough, you are not likely to be out of bound.

You could cache the transform:

private new Transform transform;
void Start(){
   transform = base.transform;
}

Once you have a check returning true, the following ones won’t happen so change your if for if/else if.

If the camera is not moving then store the values instead of making them up each round. If it moving cache the Transform of the camera:

Transform cam;

void Start(){
   cam = Camera.main.transform;
}

Those are little details that may get your fps a little bump up.

As a result:

private new Transform transform;
private Transform cam;
void Start(){
   transform = base.transform;
   cam = Camera.main.transform;
}
void Update(){
   Vector3 position = transform.position;
   Vector3 camPos = cam.position;
   if((position - camPos).sqrMagnitude > range) return;

   if (position.y < camPos.position.y-7)
   {
      transform.position.y = position.y+14;
   }

   else if (position.y > camPos.position.y+7)
   {
      transform.position.y = transform.position.y-14;
   }

   else if (position.x < camPos.position.x-12)
   {
      transform.position.x = position.x+24;
   }

   else if (position.x > camPos.position.x+12)
   {
      transform.position.x = position.x-24;
   }
}

Are you looking to iterate over an Array?

        for (int i = 0; i < starArray.Length; i++)
        {
            //  Do something here.
            //  Use the i variable to control which element of the array you wish to manipulate, instead of directly using a specific integer to determine which element to use.
        }

        foreach (GameObject star in starArray)
        {
            //  Do something here.
            //  Use the star variable as the reference to the current element in the array that the loop is looking at.
        }

A for/foreach loop is a great way to iterate over an Array and provide specific code to apply to each element.

Is this what you were after?

you can do several things:

you could try looking at the c# Hashtable class and sort the stars in it by distance
that way you can apply for example on all stars up to a distance of X one thing and the rest an other thing and its much easier and its more efficient

  1. if your moving and the stars stay at place then its a waste to calculate all this. you can separate the stars by areas and calculate distance to an area that way its less calculations per frame and its much simpler.

and the decide the star’s distance by its area without calculating anything(it will give less accurate results but its enough for these kind of things)

i hope i helped :slight_smile: