Manipulating array variables

Hello!

I’m making game with villages; so I need to assign each villager to it’s village (same with buildings)

I have an array variable that is empty.
That variable will be container of GameObjects (villagers)

the number of gameobjects is constantly growing
so how can I use .Add() function if I want to add GameObject (or some other array ‘moduling’ function)

I don’t understand 100% how “Array” variables are working.
They can be strings, they can be int, whatever, but when I want to make Array variable for gameobject it won’t make it.

How can I solve this problem?

what I’ve tried:

1st)
PICK ALL HUMANS in one variable

var HumansAll : GameObject[ ] = GameObject.FindGameObjectsWithTag (“Human”);

THEN CHECK each humans’ ID (ID is in their script as int variable)
With that I find which village are they from, but I can’t move them (GAMEOBJECT) to its village variable because of same problem .Add() and .Push() Don’t work for gameobject arrays

2nd)
When instantiating human it get’s ID,

THE IDEA WAS to give TAG to the human like “Human0” or “Human1”… “Human”+ID
THEN to pick them with
Humans = GameObject.FindGameObjectsWithTag (“Human”+ID);

BUT I CAN’T USE TAGS if they are not pre-setted (and I’m thinking about using random number of villages)

3rd)
I want to do simmilar but with NAMES like “Human0” as the name but I don’t know how would I pick them all in one array if they would have same names.

Just replace your Array to the System.Collection.List type. It is well supported by Unity Inspector, and has Add() method.

public class MyClass : MonoBehaviour
{

public System.Collection.List<GameObject> Vilagers = new System.Collection.List<GameObject>();

}

ArrayList seem to be popular. I;ve used them a lot but am no pro with them. They do come with all the cool Add() Remove() Sort() functions though.

So are u using builtin arrays or Js style arrays () or [ ] when being defined?

For a Builtin GameObject array to show in the inspector try (eg) var myObjs : GameObject[ ];

Off Topic @ Patico - Did you find a solution to the line rendering lightning? I made something cool and am willing to share if you can use js.

Ahm y now you remind me.

“public var Humans = new Array ();”

instead of

“public var Humans : GameObject[ ];”

such a stupid mistake…

TY

You should never use Array(); it’s slow and untyped. Use a generic List instead.

Nope, that’s not really any better than Array(). Use generic List.

–Eric

Script attached on Village (Spawn/homeblock)

...
public var Houses_1 = new Array ();
public var Houses_2 = new Array ();
public var Houses_3 = new Array ();
...

Script attached on Villager (unit)

...
var ExistingHouses = new Array ();

...

//JOIN houses lvl 1  2 then join lvl3
ExistingHouses = spawnerScript.Houses_1.Concat(spawnerScript.Houses_2);
ExistingHouses = ExistingHouses.Concat(spawnerScript.Houses_3);
for (i=0; i<ExistingHouses.length ; i++)
     if (Vector3.Distance(ExistingHouses[i].transform.position, PlacPos)<2) buildOn = false;

1st problem - I have to use Array() type because I use “.Concat” function which wouldn’t work if “ExistingHouses” is assigned as built in type (var ExistingHouses : GameObject[ ]:wink:

2nd problem - When I use Array() type I JOIN arrays THAT ARE CONTAINING GAMEOBJECTs into one Array() which saves that GAMEOBJECTs as OBJECTs so I can’t manipulate with them properly

this is the error line:
…ExistingHouses*.transform.position[/COLOR]…*
‘transform’ is not a member of an ‘Object’
how to solve this problem?

Did you try to do this:

for (i=0; i<ExistingHouses.length ; i++)
{
     GameObject go = ExistingHouses[i] as GameObject;
     if(go != null)
          if (Vector3.Distance(go.transform.position, PlacPos)<2) buildOn = false;
     else
          Debug.LogWarning("ExistingHouses["+i+"] is not a GameObject");
}

thank you guys!

I managed to solve the problem

Patico - I’m still amateur in scripting so I don’t know how “as GameObject” works I mean it’s more like I don’t know WHEN I can use it - that’s why I didn’t had that solution on my mind. I understand your code.

tonyd - I used your way I see it’s similar as Paticos’ but shorter. and thank you for tips, I’ll use them!

Should point out the reason for this. ArrayList is untyped so it stores everything as an “Object”. Boxing and Unboxing occurs as it converts your object type to object, and then back to your type. For instance:

var al = new ArrayList();

var p = new Person { Name = "John", Age=40 };

al.Add(p);

This actually converts your instance of type “Person” to type “Object” and stores it in the ArrayList. When you get it back out, it has to convert it back to Person. Not only that, but you could store multiple different types of objects in your ArrayList so you could potentially run into issues.

var list = new List<Person>();
var p = new Person { Name = "John", Age=40 };
list.Add(p);

Now you have a list that’s already of type Person… it knows what’s going in and coming out and does not box and unbox your values.

Technically that’s not boxing/unboxing because Person isn’t a value type. Also note that ArrayList doesn’t cast back to the original type upon retrieval which is where the real danger lies. Because an ArrayList can hold any type there’s no way to know the type of the thing you’re getting back. Generic collections safe guard you from this by throwing an exception at compile time as opposed to run time which is always more desirable.

Temporary brain slip… you’re correct, if Person were a class it would not be boxed and unboxed. If it were a struct, however, it would be since structs are value types and not reference types:

public struct Person
{
    public string Name;
    public int Age;
}

So yeah, one big benefit in the case of classes is having a typed collection so you always know what you’re getting back. Although, you could just as easily do: List and have one element be an Array and another be a List. In this type of scenario though, you would likely be working with the methods exposed by IEnumerable (or whatever interface you specified) and not casting the object yourself. Additionally, the nice thing about generics is that the types are determined at compile time and not at run time so there are performance benefits since you don’t have to do the casting.