- Home /
Use custom class like array
Is it possible to use a custom class similar to an array, like accessing the children of transform, or the AnimationStates in a Animation object (which actually is really strange... you can access it by using a string?!)?
Here are examples of what I mean:
for (var child : Transform in transform) {
child.position += Vector3.up * 10.0;
}
or
for (var state : AnimationState in animation) {
state.speed = 0.5;
}
Answer by Bunny83 · Feb 19, 2012 at 01:49 PM
Transform implements a common interface called IEnumerable. This interface forces the class to provide a GetEnumerator() function which should return an object that implements the IEnumerator interface. With this enumerator you can "enumerate" through "whatever" the class want.
For example, this is how the Transform IEnumerator looks like:
// C# public sealed class Transform : Component, IEnumerable { private sealed class Enumerator : IEnumerator { private Transform outer; private int currentIndex = -1; public object Current { get { return this.outer.GetChild(this.currentIndex); } } internal Enumerator(Transform outer) { this.outer = outer; } public bool MoveNext() { int childCount = this.outer.childCount; return ++this.currentIndex < childCount; } public void Reset() { this.currentIndex = -1; } }
public IEnumerator GetEnumerator()
{
return new Transform.Enumerator(this);
}
// Rest of Transform
}
Now if you use a transform in a foreach-loop the compiler sees that it implements the IEnumerable interface and use GetEnumerator() to get an enumerator-object which it can use to loop through the collection.
This:
// C#
foreach (Transform child in transform)
{
// ...
}
performs actually something like this:
IEnumerator tmpEnumerator = transform.GetEnumerator();
while (tmpEnumerator.MoveNext())
{
Transform child = (Transform)tmpEnumerator.Current;
// ...
}
edit
To use a class "like an array" you can use an Indexer.
Indexers and additional interfaces are not supported by UnityScript(Unity's Javascript) at the moment. The only way would be to use C#
Thank you! At least I know how it would work.... It's a shame, that this is not possible in UnityScript, but if I really need this feature I could still make a class in C# and use it in UnityScript!
Answer by Berenger · Feb 18, 2012 at 09:58 PM
That for loop can be used with any arrays, no matter what is in there. I think AnimationStates is a hashtable, which mean you can access elements with a key, a string in that case.
But animation and transform aren't arrays... $$anonymous$$y question is how I can make a class and access a variable like if it were a array. Is this even possible in JavaScript?
Animation (not AnimationState, my bad) and Transform are arrays-like actually (it's called a collection) and your code already work, test it.
I was about to say how Transform contains a collection of Transforms, but itself is not an array. But I see your point - it's being accessed in that 'for' loop as though it were. So we would normally think it would be
for (t : Transform in trans) // where trans is declared as Transform[], but it's not!
$$anonymous$$aybe there's a way to have a 'get' method that returns []
Is there any way to reproduce this with a custom class? For example if I have the custom class "Army" with the variable "soldiers : Soldier[]", it would be much cleaner to write: var army : Army;
for(var soldier : Soldier in army) {
//do stuff
}
Of course I could write army.soldiers, but I am just interested if I could do the same thing as the Unity devs!
Btw... I know that the code above is working.. I wrote them as examples for what I want to recreate.