Scaling by distance, performance problem

I have this script attached to the player object:

#pragma strict
var tempobjs : GameObject[];
var allobjs = new List.<GameObject>();
var i : int = 0;

function Start () {
	tempobjs = GameObject.FindObjectsOfType(GameObject);
	Debug.Log(tempobjs.length);
	for(i=0;i<tempobjs.length;i++){
		//Debug.Log(tempobjs[i]);
		if(tempobjs[i].GetComponent(ObjectData)!= null) allobjs.Add(tempobjs[i]);
	}
}

function Update () {
	var distscale : float;
	for(i=0;i<allobjs.Count;i++){
		distscale = (1 - Vector3.Distance(transform.position, allobjs[i].transform.position) / (Vector3.Distance(transform.position, allobjs[i].transform.position)+.01));
		//Debug.Log(distscale);
		//Debug.Log(allobjs[i]);
		allobjs[i].transform.localScale = Vector3(1,1,1)*allobjs[i].GetComponent(ObjectData).objSize*distscale;
	}
}

It works exactly as I need it to, but it DESTROYS performance and turns the game into a slide show. Is there a more effective way to do this? localScale was the only thing I could even find to change an objects size at runtime.

If possible I would try caching a few of those components that you are frequently accessing in there. Most importantly the blatant GetComponent call to grab the ObjectData component at the end of the for loop.

This code assumes you add the same Awake method to your ObjectData class that this code shows.

NOTE ** Untested code (also not 100% on UnityScript syntax):

#pragma strict

var tempobjs : GameObject[];
var allobjs = new List.<ObjectData>();
var i : int = 0;

private var cachedTransform : Transform;

function Awake()
{
	cachedTransform = GetComponent(Transform);
}

function Start () 
{
    tempobjs = GameObject.FindObjectsOfType(ObjectData);
    for(i=0;i<tempobjs.length;i++)
    {
		if(tempobjs[i].GetComponent(ObjectData) != null) allobjs.Add(tempobjs[i].GetComponent(ObjectData));
    }
}

function Update () 
{
    var distscale : float = 0f;
    for(i=0;i<allobjs.Count;i++)
    {
        distscale = (1f - Vector3.Distance(cachedTransform.position, allobjs[i].cachedTransform.position) / (Vector3.Distance(cachedTransform.position, allobjs[i].cachedTransform.position)+.01f));
        allobjs[i].cachedTransform.localScale = Vector3(1,1,1)*allobjs[i].objSize*distscale;
    }
}

Instead of using Vector3.Distance you could try and use square magnitude… link! This should make it a little faster.

Calling GetComponent every frame is extremely processor intensive fyi. Doing this for lots of objects every frame is the major reason the performance is slow.
To fix this you could consider making a List of ObjectDatas too. With this you would just have to make sure that allobjs[i] and allobjDatas[i] are referring to the same object or stuff would get really messed up. Assuming this is the way you go that line of code with the GetComponent would look like this instead:

allobjs[i].transform.localScale = Vector3(1,1,1)*allobjDatas[i].objSize*distscale;

This isn’t the most elegant solution but should work. I am sure someone with more experience then I will tell us both why I have failed miserably and we shall learn a better way to do it.

Damn, beaten to the punch.

Kyle:

Your syntax and code is almost dead on. I only had to make a couple of changes to get it to work.

7: Took out ‘private’
16: Changed ‘ObjectData’ to ‘GameObject’ (that’s what its supposed to be.)

It still worked like it was supposed to, unfortunately, it did not help with performance. What is the cachedTransform change supposed to do? Any other suggestions for performance improvements?

KHopcraft:

I tried to do something similar without an array but it didn’t work, Ill try it with an array like you suggested and see if that helps.

UPDATE: Tried setting up the ObjectDatas in a list. Got it working that way, but again, still no help on performance. The problem definitely stems from line 21 in my original post. No matter how I have changed it so far, commenting it out solves all performance issues.

Basically:

allobjs[i].transform

is the same as:

allobjs[i].GetComponent(Transform)

and is just as bad on performance.

I’m wondering how many objects are being updated every frame in that array?

Right now allobjs is only holding 6 items. A typical finished scene will probably have 50+ objects that will end up in that list.