- Home /
List of Vector2 - Madness looms in simple script
Hi to all!
I'm about to go crazy. Trying to store values in a list of Vector2, and it's just not working. Here's a script demonstrating the issue:
function Test()
{
var arr = new float[100];
for (val in arr)
{
val = Random.value;
}
var tempMaxList = List.<Vector2>();
tempMaxList.Add(Vector2.zero);
for(var i:int=0;i<arr.length;i++)
{
if(arr[i]>tempMaxList[0].y)
{
tempMaxList[0].x = i;
tempMaxList[0].y = arr[i];
Debug.Log(tempMaxList[0]+" "+i+" "+arr[i]); //tempMaxList[0] is 0,0, WTF???
}
}
}
If I replace tempMaxList by a simple Vector2 var, everything is fine.
I'm sure epic face palming will follow, but I just can't see what I'm doing wrong here...
just tested with a list of floats ins$$anonymous$$d of Vector2, works fine too. WTF?
Answer by Bunny83 · Aug 02, 2012 at 11:39 AM
First this usually doesn't work:
var arr = new float[100];
for (val in arr)
{
val = Random.value;
}
I don't use UnityScript, but a foreach / for-in loop uses an IEnumerator to iterate through the array. You can never assign values to the iterator variable since it's always just a copy of the value stored in the array. Use a normal for loop:
var arr = new float[100];
for (var n = 0; n< arr.Length; n++)
{
arr[n] = Random.value;
}
Second, your problem that the returned values are 0,0 is that Vector2 is a value type. When you use the indexer of your List you get a copy of the item. Changing the members of this copy won't change the item in the list.
Use either :
for(var i:int=0;i<arr.length;i++)
{
if(arr[i]>tempMaxList[0].y)
{
tempMaxList[0] = new Vector2(i,arr[i]);
}
}
or
for(var i:int=0;i<arr.length;i++)
{
if(arr[i]>tempMaxList[0].y)
{
var tmp = tempMaxList[0];
tmp.x = i;
tmp.y = arr[i];
tempMaxList[0] = tmp;
}
}
Lastly, I don't get why you use a List. You just add one item and always use this like a single variable. So the whole thing could be done like this:
function Test()
{
var arr = new float[100];
for (var n = 0; n< arr.Length; n++)
{
arr[n] = Random.value;
}
var tempMax = Vector2.zero;
for(var i = 0; i < arr.length; i++)
{
if(arr[i] > tempMax.y)
{
tempMax.x = i;
tempMax.y = arr[i];
Debug.Log(tempMax + " " + i + " " + arr[i]);
}
}
}
Thanks for the detailed reply! Step by step: 1) The random values were assigned allright, but thanks for the tip!
2) Thanks, that's it.
3) The script I provided is a much simplified version. I'm getting maximum values of a float[] every x float.
Cheers!
This is actually the point where reality catches up with you ;) UnityScript has implemented a lot automatic conversions to make your life "simpler". Like the .position property of Transform. It's also a valuetype and accessed by a get method.
This line usually shouldn't work:
transform.position.x = 5;
but Unity compiles this line as:
var tmp = transform.position;
tmp.x = 5;
transform.position = tmp;
This is a special rule they implemented to make your code look simpler. In most cases it actually gets more complicated.
This:
transform.position.x = 1;
transform.position.y = 2;
transform.position.z = 3;
transform.position.y += 5;
would be compiled to something like:
var tmp = transform.position;
tmp.x = 1;
transform.position = tmp;
var tmp2 = transform.position;
tmp2.y = 2;
transform.position = tmp2;
var tmp3 = transform.position;
tmp3.z = 3;
transform.position = tmp3;
var tmp4 = transform.position;
tmp4.y += 5;
transform.position = tmp4;
The true code (reflected as C#) looks like this:
int num = 1;
Vector3 position = this.transform.position;
float num2 = position.x = (float)num;
Vector3 vector = this.transform.position = position;
int num3 = 2;
Vector3 position2 = this.transform.position;
float num4 = position2.y = (float)num3;
Vector3 vector2 = this.transform.position = position2;
int num5 = 3;
Vector3 position3 = this.transform.position;
float num6 = position3.z = (float)num5;
Vector3 vector3 = this.transform.position = position3;
float y = this.transform.position.y + (float)5;
Vector3 position4 = this.transform.position;
float num7 = position4.y = y;
Vector3 vector4 = this.transform.position = position4;
No need for quotes around "simpler", Unityscript does in fact make things easier. The point of compilers is to do exactly that, take your simplified code and spit out more complicated code behind the scenes. No need for masochism...or do you insist on unrolling your own loops too? ;) By the way, this:
var arr = new float[100];
for (val in arr)
{
val = Random.value;
}
does work just fine in Unityscript.