Index out of range problem (I think) gameobject array

I have written a script here that is supposed to gather a list of objects to be circled, and apply a guitexture circle around each one. I am having 2 problems.

It is not placing the textures in the right places. I only get 2 placed, one stretched horizontally in the center, and one stretched horizontally centered in the bottom left corner (3/4 of it is cut off). I know there should be more than that and that those 2 spots are not the right locations. All the objects are properly tagged and parts of this code have worked before when it was applied to a single object that was selected. In fact, the only things that have changed since the last working version in DrawHUDMap() is the instantiate and the arrays. replace the arrays with single gameobject variables and comment out the instantiate line and youll more or less have the working code I had before.

The other problem is an error:
IndexOutOfRangeException: Array index is out of range.
(wrapper stelemref) object:stelemref (object,intptr,object)
HUDMap.DrawHUDMap (UnityEngine.GameObject[ ] targets, Color ringcolor) (at Assets/Scripts/HUDMap.js:76)
HUDMap.Update () (at Assets/Scripts/HUDMap.js:25)

It seems to me if the out of range error there is fixed, it will probably draw the circles correctly.

Here is the script. Sorry about all the commented code, I’ve been trying to work through this, unsuccessfully, since I added arrays. I didn’t clean it up so the error would show the correct line in this code.

#pragma strict
var tring : GameObject[];
var solar : GameObject[];
var neutral : GameObject[];
var friendly : GameObject[];
var enemy : GameObject[];
var tar : GameObject[];
var RingPrefab : GameObject;
var totaltargets : int = 0;
var ontarget : int = 0;
function Start () {
	solar = GameObject.FindGameObjectsWithTag("Solar");
	neutral = GameObject.FindGameObjectsWithTag("Neutral");
	friendly = GameObject.FindGameObjectsWithTag("Friendly");
	enemy = GameObject.FindGameObjectsWithTag("Enemy");
	tar = GameObject.FindGameObjectsWithTag("TarRing");
}

function Update () {
	for(var i=ontarget;i>0;i--){
		Destroy(tring[i]);
	}
	ontarget = 0;
	//Set the solarbody target rings and draw them blue.
    if(solar.length>0) DrawHUDMap(solar,Color(0,0,1,1));
    //Set the friendly target rings and draw them green.
    if(friendly.length>0) DrawHUDMap(friendly,Color(0,1,0,1));
    //Set the neutral target rings and set them yellow.
    if(neutral.length>0) DrawHUDMap(neutral,Color(1,0.92,0.016,1));
    //Set the enemy target rings and set them red.
    if(enemy.length>0) DrawHUDMap(enemy,Color(1,0,0,1));
	
	
	//Set the selected target ring and draw it white.
	//Do this after the regular map draw so it doesnt get covered by a different color.
	//Not working, throws a NullReferenceException. when locktarget != null
    tar[0]=GetComponent(GUIs).locktarget;
    if(tar[0] != null){
    	DrawHUDMap(tar,Color(1,1,1,1));
    }else if(tar[0] == null){
    	tring[ontarget].guiTexture.enabled=false;
    }
    
}

function DrawHUDMap (targets:GameObject[],ringcolor:Color){
   	for(var i=0;i<targets.length;i++){
   		var target : GameObject = targets[i];
    	var bounds : Bounds = target.collider.bounds;
 	  	var cam : Camera = Camera.main;
       	var center : Vector3 = cam.WorldToScreenPoint(bounds.center);
       	var radius : float = 0;
   		var r : float = 0;
     	// top
  	 	r = Vector3.Distance(center, cam.WorldToScreenPoint(new Vector3(bounds.max.x, bounds.max.y, bounds.max.z)));
   		if(r > radius) radius = r;
   		r = Vector3.Distance(center, cam.WorldToScreenPoint(new Vector3(bounds.min.x, bounds.max.y, bounds.max.z)));
   		if(r > radius) radius = r;
   		r = Vector3.Distance(center, cam.WorldToScreenPoint(new Vector3(bounds.max.x, bounds.min.y, bounds.max.z)));
   		if(r > radius) radius = r;
   		r = Vector3.Distance(center, cam.WorldToScreenPoint(new Vector3(bounds.min.x, bounds.min.y, bounds.max.z)));
   		if(r > radius) radius = r;
      	// bottom
  	 	r = Vector3.Distance(center, cam.WorldToScreenPoint(new Vector3(bounds.max.x, bounds.max.y, bounds.min.z)));
   		if(r > radius) radius = r;
   		r = Vector3.Distance(center, cam.WorldToScreenPoint(new Vector3(bounds.min.x, bounds.max.y, bounds.min.z)));
   		if(r > radius) radius = r;
   		r = Vector3.Distance(center, cam.WorldToScreenPoint(new Vector3(bounds.max.x, bounds.min.y, bounds.min.z)));
   		if(r > radius) radius = r;
   		r = Vector3.Distance(center, cam.WorldToScreenPoint(new Vector3(bounds.min.x, bounds.min.y, bounds.min.z)));
   		if(r > radius) radius = r;
     	//center is the objects position, z is the camera distance value
  	 	//diameter will be the width of the texture containing the selection ring.
   		//radius = radius*1.25;
   		
		tring[ontarget] = Instantiate(RingPrefab, target.transform.position, target.transform.rotation);
		//Instantiate a ring. here, then apply this code to it
   		if(radius < 10)	radius = 10;
   		if(center.x>0  center.x<Screen.width  center.y>0  center.y<Screen.height  center.z>0){
	   	 	tring[ontarget].guiTexture.color = ringcolor;
   		 	tring[ontarget].guiTexture.color.a = 400/(radius*radius)+0.1;//(radius*10/250*10)+5;
    		//Debug.Log(tring.guiTexture.color.a);
    		tring[ontarget].guiTexture.enabled = true;
   			tring[ontarget].guiTexture.pixelInset = Rect(center.x-Screen.width/2-radius,center.y-Screen.height/2-radius,radius*2,radius*2);
   			
   	 	}else if(center.x<=0 || center.x>=Screen.width || center.y<=0 || center.y>=Screen.height || center.z<0){
    		tring[ontarget].guiTexture.enabled=false;
    	} 
    	ontarget++;
    	if(ontarget>totaltargets) totaltargets = ontarget;
    	//Debug.Log(center.z);

    	//if (center.z<0)
    		//tring.guiTexture.enabled=false;
   		//Debug.Log(guilocation);
   	}
}

So, I guess my basic questions here are probably: How do I increase the size of an array? Or better yet, How do I define it as a dynamic array? Is that the problem I’m having with the rings not being there, or in the right spots?

Thanks

EDIT: You can ignore line 36 about the null reference error, that’s been fixed.

You can use System.Array.Resize, but in general you should use a generic List if you want a dynamic array.

–Eric

I’ll look into generic Lists then. Thanks

Ok Switched to lists and now I’m getting this:

Assets/Scripts/HUDMap.js(85,46): BCE0023: No appropriate version of ‘UnityEngine.Object.Instantiate’ for the argument list ‘(UnityEngine.GameObject, UnityEngine.Vector3, UnityEngine.Vector3)’ was found.

line 84-93:

if(center.x>0  center.x<Screen.width  center.y>0  center.y<Screen.height  center.z>0){
	   	 	tring.Add(Instantiate(RingPrefab, Vector3(center.x-Screen.width/2-radius,center.y-Screen.height/2-radius,0), Vector3(0,0,0)));//Error from this line
	   	 	tring[ontarget].guiTexture.color = ringcolor;
   		 	tring[ontarget].guiTexture.color.a = 400/(radius*radius)+0.1;//(radius*10/250*10)+5;
    		//Debug.Log(tring.guiTexture.color.a);
    		tring[ontarget].guiTexture.enabled = true;
   			tring[ontarget].guiTexture.pixelInset = Rect(center.x-Screen.width/2-radius,center.y-Screen.height/2-radius,radius*2,radius*2);
   			ontarget++;
    	
   	 	}

See the docs for Instantiate; it takes an Object, a Vector3, and a Quaternion.

–Eric

Wow, I feel like such an idiot. I seen the 3 values in the transform component in the inspector and just assumed it was a Vector3 just like the other 2. Thanks for the help I have it working exactly how I want now and learned a couple of things in the process. I guess from now on I’ll check the docs for everything I learn in tutorials that I have not already checked (and probably a few that I have:smile:)

Actually the transform component is showing you Transform.eulerAngles, which is a Vector3. However that’s not what’s used for Instantiate. (You can use Quaternion.Euler in that case though. An overload for Instantiate that accepted a Vector3 for eulerAngles might be nice. Also an overload that used Quaternion.identity as a default would be nice, since I use that frequently, so all I’d have to supply would be the object and position. Anyway… :wink: )

–Eric