AS2 to AS3: Dynamic instance names
January 20th, 2009
There are a handful of questions that get posted over and over again in the forums that all boil down to the same issue: setting up instance names in AS3 doesn't work.
Everyone who hits this problem comes up with a plan of attack that goes something like this:
Which sounds pretty good on paper, but generally ends with this:
So what went wrong? This is easily one of the biggest stumbling blocks for new AS3 users, and Adobe goes to great lengths to ignore it and pretend the problem doesn't exist. Here's the secret: Instance names don't really exist!
Ok, more specifically, when you assign an instance name in Flash, there is secret code generated for you behind the scenes that creates two variables which work together to give you the perception of an instance name. To do the same thing in your own code you would use this:
A .name is not a thing
The first half of this solution is repairing a misconception; There is a general belief that setting the name property on an object gives it mystical powers. It doesn't. The name is just a string that is attached to objects for your convenience, it is not a unique identifier. Saying you want to play the clip named "mc3" is just as silly as saying you want to play the clip at .x = 50, or .alpha = 1 – these are all attributes of objects, not pointers to the objects themselves.
So with all of that said, now it's time to contradict myself. Adobe has tried to redeem themselves by making a little workaround function for this problem. It comes in the form of the getChildByName("mc3") method. It's not particularly efficient and you can have multiple things share one name so it's not great code practice, but it is a handy tool to be aware of in a pinch.
Create dynamic variables at runtime
Having completely debunked .name, we've now got the other half of this issue to deal with - how to create dynamic vars in AS3. Again the answer is, you can't. What you can do, is leverage a single Array to point at all your clips at once.
That code will create 5 distinct MovieClips and stick them all into the clips Array under different indices. To get a specific clip back later, you just have to know the index:

January 25th, 2009 at 12:33 pm
Thanks so much for this Rob. This is an absolute HUGE help to me! Thanks so much and keep up the great work!
January 27th, 2009 at 6:41 am
Thank you so much! This is one of those stupid AS3 things that I just could not wrap my head around, even after working through several projects and class based OOP, etc
February 7th, 2009 at 2:08 pm
What about using a Dictionary?
February 16th, 2009 at 4:58 pm
Hey,
Thanks for the info. This is just what I was looking for. Now I just wish that I had thought searching for this sooner, I just wasted several hours trying to get ‘.name’ to work!
February 25th, 2009 at 5:38 am
isn’t it handier to use clips.push(mc) instead of clips[i] = mc in the loop?
February 25th, 2009 at 7:14 am
Jim – that’s a great point. I used the bracket notation here to show the index number going in and being preserved later; if you wanted to optimize further you could drop the .name tag completely (if you aren’t using it for anything) and try a faster loop style.
March 19th, 2009 at 10:35 am
Man, I was about to try this but wanted to see if anybody else attempted it first. I am glad to see that it logically works. Thanks for the example!
I have got to let others know. This has been a problem in numerous forums.
April 9th, 2009 at 3:05 am
I commonly use systems where attributes are added dynamically to objects. I fact, the application doesn’t even know what the attribute is called in advance, because even that is dynamic.
Things like:
this['mc3'].play();
Can in fact work, since dynamic objects work in a dictionary like way. I’m sure it isn’t “proper” in some peoples mind, but done right it can work well.
Stuff like this in loops can be useful.
propertyName = “mc” + i;
mc = new MovieClip();
this['propertyName'] = mc;
addChild(mc);
(I don’t known if this exact code works, but I do similar stuff often.)
April 15th, 2009 at 5:07 pm
Perfect!!!! Very clear and concise !!!
April 30th, 2009 at 9:05 am
finally! thanks!
April 30th, 2009 at 3:59 pm
hi there,
I’m running into exactly the same problem but within a class.
Basically I need to set a new id each time an instance of that class is created so I can use it later in the resetMenu function.
the .gs is GreenSock tweening classes.
ANY IDEAS ARE WELCOME!
Thanks.
Below is the .as code:
package{
import flash.display.*;
import flash.events.Event;
import flash.events.MouseEvent;
import gs.*;
public class customBtn1 extends MovieClip {
//*************************
// Properties:
public var xPos:uint;
public var yPos:uint;
public var btnId:int;
private var totalButtons:int = 5;
private var i:uint = 0;
public var counter:uint;
private var myBtn:MovieClip;
private var btnNames:Array = [];
private var target:MovieClip;
private var theName:String;
//*************************
// Constructor:
public function customBtn1(i) {
myBtn = this;
//trace(myBtn);
myBtn.name = ‘btn’ + i;
btnNames[i] = myBtn.name;
trace(‘BBB= ‘ + myBtn.name);
trace(btnNames[i]);
init();
}
private function init():void {
buttonMode = true;
addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
addEventListener(MouseEvent.CLICK, clickHandler);
}
private function getBtnId():void{
trace(‘name= ‘ + name);
if(name.length==4){
btnId = int(name.charAt(3));
//trace(‘btnId= ‘ + btnId);
}else{
btnId = int(name.substring(3,5));
//trace(‘btnId= ‘ + btnId);
}
}
private function resetMenu(target):void{
trace(‘///////////////// at Reset Menu’);
//trace(‘btnId= ‘ + btnId);
trace(‘target >>>>>= ‘ + target);
for(i=0;i<totalButtons;i++){
if(i==btnId){
trace(‘PPP ‘ + i +’ = ‘+ btnNames[i]);
//trace(‘i IS EQUAL TO btnID’);
target.removeEventListener(MouseEvent.MOUSE_OUT,mouseOutHandler);
}else{ //trace(‘i IS NOT EQUAL TO btnID’); trace(‘PPP ‘ + i +’ = ‘+ btnNames[i]); //TweenLite.to(theMov, .5, {tint:0×999999}); //btnNames[i].mouseEnabled = true;
}
}//END LOOP
}
public function setPosition(xPos:uint,yPos:uint) {
this.x = xPos;
this.y = yPos;
}
private function mouseOverHandler(event:MouseEvent):void {
TweenLite.to(event.target, .5, {tint:0xff0000});
}
private function mouseOutHandler(event:MouseEvent):void {
TweenLite.to(event.target, .5, {tint:0×999999});
}
private function clickHandler(event:MouseEvent):void {
event.target.mouseEnabled = false;
getBtnId();
resetMenu(event.target);
}
}
}
And in the .fla:
var totalButtons:uint = 5;
var i:uint;
var spacing:uint=70;
for (i = 0; i < totalButtons; i++){
var myBtn:customBtn1= new customBtn1(‘btn’ + i);
myBtn.setPosition((spacing * i) + 30,50);
this.addChild(myBtn);
}
May 12th, 2009 at 11:35 pm
I love you and I want to have your babies
August 25th, 2009 at 6:08 am
Lovely. Thank you. Been banging my head on this one for a while.
October 13th, 2009 at 12:59 pm
So using this method “clips[3].play();”, how would you attach an event listener to clips[3]?
October 27th, 2009 at 1:50 pm
very nice! you save my time, thanks
November 26th, 2009 at 2:58 pm
Hey Larry,
This is a little after the fact but I believe you just add your event listener to the mc when you generate your array e.g. mc.addEventListener(MouseEvent.CLICK, eventHandler)
I hope this helps you are someone else.
Novian
December 2nd, 2009 at 8:35 pm
This shold be the cover page for every Action Script 3.0 manual!! Would have saved me countless hours.
January 4th, 2010 at 11:05 pm
THANK U VRY MUCH………
January 19th, 2010 at 8:08 am
Hi, thanks for this, I was desperate before I discover this site. You helped me a lot.
But I think I have better solution:
Let’s say we want to add multiple instances of one object from library (for example some points/movieclip) and we then want to click on them and we also want from Flash to know which instances we clicked.
We can work with names and strings but it is difficult and no effective. The idea with array is great but we don’t need make new variable for instance. It is easier to do something like this:
var i:uint = 0;
var points:Array = []; //array of future points
and then when we add Movieclip on stage we use something like this:
points[i] = new Movieclip();
i++;
each instance is stored in one element of array so we can call it through index of array.
For examle. if we have some Mouse.CLICK listener we can write inside the function of listener:
points[points.indexOf(event.target)];
Now we know exactly on which instance we clicked.
Hope it is undersandable. :)
January 30th, 2010 at 4:10 pm
Hi, I am trying to get an instance name of a sprite I created with code so I could move it with arrow keys but, it’s not working. Could you tell me how to fix it/what title to use so i can move my sprite? Thanks.
Code:
import flash.events.*;
var size:int=50;
// size of the object
stage.addEventListener(Event.ENTER_FRAME,CreateObjectListener);
function CreateObjectListener(event:Event):void {
var objects:Array=[];
for (var i = 0; i < 5; i++) {
var object:Sprite = new Sprite();
object.name="object"+i;
addChild(object);
object.x=275;
object.y=200;
objects[i]=object;
}
with (object.graphics) {
lineStyle(1, 0×000000, 1);
beginFill(0xFF0000, 1);
moveTo(-size/5,-size);
lineTo(size/1,-size);
lineTo(size/1,size);
lineTo(-size/1,size);
lineTo(-size/1,-size);
}
}
February 21st, 2010 at 8:04 am
Respect
March 16th, 2010 at 12:25 pm
wuauuuuuuu!!!
te amo!!!!
Muchas gracias!!!
3 dias buscando!
desde Antofagasta Chile. !!! Te amo!!!!!
June 20th, 2010 at 8:32 am
[...] zwischen Instanzname und Name Eigenschaft so nicht ganz klar. Geholfen hat mir dieses Tut: Calypso88 Blog Archive AS2 to AS3: Dynamic instance names. Ich komme trotzdem noch nicht ganz weiter. Es tun sich mir da mehrere Fragen auf. Wenn ich so [...]