Jump to content

Un-parenting objects


Recommended Posts

Hello everyone!

I am new to the forum and I love Pixi.js so far. I find it really versatile and clear.

I have one doubt though, about the "parenting system". I am allowed to to do addChild() on an existing object on the stage (let's say a sprite, to another one) but if I remove it by removeChild() it does not "un-parent" it (like parent = null or something  similar) but apparently it gets completely removed (and not rendered anymore).


How can I un-parent properly, then? 
I tried to set the parent property of the child object to null, undefined (but this generates errors) and if I assign it to itself (like the object is is own parent, to express that it has no parent at all) the transforms are growing exponentially (indeed in the code of pixi it shows that the transform of the parent is always added).

Apparently then, the only way to "un-parent" a child is to set its parent to the stage it is rendered on.


Doing so though, will lose every information about the parent's transform and the eventual offset set to the parented child (cause when parenting the transforms become exactly the one of the parents so you probably want to set an offset after parenting), becomes the actual position of the now-un-parented child.

I tried to sum the parent's values before setting the parent to the stage but the rotation/position values look weird when i un-parent the child.


I give you a dirty tweaked version of the bunny example to let you understand what i mean:

// create an new instance of a pixi stagevar stage = new PIXI.Stage(0x66FF99);// create a renderer instancevar renderer = new PIXI.WebGLRenderer(400, 300);//autoDetectRenderer(400, 300);// add the renderer view element to the DOMdocument.body.appendChild(renderer.view);requestAnimFrame( animate );// create a texture from an image pathvar texture = PIXI.Texture.fromImage("bunny.png");// create a new Sprite using the texturevar bunny1 = new PIXI.Sprite(texture),	bunny2 = new PIXI.Sprite(texture);// center the sprites anchor pointbunny1.anchor.x = 0.5;bunny1.anchor.y = 0.5;bunny2.anchor.x = 0.5;bunny2.anchor.y = 0.5;// move the sprite t the center of the screenbunny1.position.x = 200;bunny1.position.y = 150;bunny2.position.x = 300;bunny2.position.y = 250;stage.addChild(bunny1);stage.addChild(bunny2);bunny1.addChild(bunny2);bunny2.position.x = 100;bunny2.position.y = 100;var removed = false;function animate() {    requestAnimFrame( animate );    // just for fun, lets rotate mr rabbit a little    bunny1.rotation += 0.01;    // still for fun, lets un-parent the child and see what happens    if (bunny1.rotation > 1 && !removed) {    	removed = true;    	//bunny1.removeChild(bunny2); // This does not un-parent! 		bunny2.position.x += bunny2.parent.position.x;	bunny2.position.y += bunny2.parent.position.y;	bunny2.rotation += bunny2.parent.rotation;    	bunny2.parent = stage;    }    // render the stage    renderer.render(stage);}

Do I need to use transformation matrixes here? I thought pixi already had them...

Any hint on this? 

Link to comment
Share on other sites

PIXI is a scene graph, you add/remove things to the graph via the add/remove child methods. If you remove a leaf from the tree, it doesn't automagically drop to the root of the tree, it is removed.


If you want to remove a child from its parent and add it to the stage, just do so:

var parent = new PIXI.DisplayObjectContainer();var child = new PIXI.Sprite(someTexture);parent.addChild(child);stage.addChild(parent);// Rendered graph is:// (stage)//   |_(parent)//     |_(child)//////////parent.removeChild(child);// Rendered graph is:// (stage)//   |_(parent)//////////stage.addChild(child);// Rendered graph is:// (stage)//   |_(parent)//   |_(child)//////////

Read up about Scene Graphs for more information. Keep in mind you are modifying a Tree data structure, there is no "fallback to root on removal" logic here.


It sounds like you want it to inherit the worldTransform matrix of the parent, without it actually being a child of that object which I don't understand. What are you trying to accomplish? Can you better define "unparent," because to me that means "remove from tree". The stage is the only object that is "rendered," all other objects are rendered from that root by walking the scene graph, there can only be one root on this tree.

Link to comment
Share on other sites

Hello xerver!


Thanks for the quick reply.


So, when i say "un-parent" i mean "do-not-have-any-parent", which in my opinion is defined as parent = null or parent = SomeKindOfEnum.Empty, more than parent = stage (even if i understand why we are doing this, because of scene-graph).


This is just my opinion about how to implement parenting (I think I would just assign parent = stage automatically on removeChild).

Anyway the way you explained it now xerver, makes more sense to me now. Thank you.


Now my problem is: i am bunny2 and i want to parent to bunny1, follow its rotation as long as i am its child and then, (when bunny1 exceeds a rotation of 1) un-parent from him, but i want to maintain my transform properties (and values) like i have never been parented to bunny1.

If you try my example you'll notice that i "click" back to my original transform values.

I hope I am explaining myself correctly...

Link to comment
Share on other sites

So, when i say "un-parent" i mean "do-not-have-any-parent",


When parent == null, then you are not in the graph and therefore not rendered.


Now my problem is: i am bunny2 and i want to parent to bunny1, follow its rotation as long as i am its child and then, (when bunny1 exceeds a rotation of 1) un-parent from him, but i want to maintain my transform properties (and values) like i have never been parented to bunny1.


There is no magic way to do this, but it is pretty trivial to just do it yourself.

bunny1.addChild(bunny2);// once rotation has reached 1bunny1.removeChild(bunny2);bunny2.position.x = bunny1.position.x;bunny2.position.y = bunny1.position.y;bunny2.rotation = bunny1.rotation;// assuming this is the same parent as bunny1, this should work.stage.addChild(bunny2);// or to be absolutely sure they share the same parent you could do:// bunny1.parent.addChild(bunny2);
Don't think of this as some "parenting system" this is just the render graph. There is nothing except the render graph, it isn't an extra feature it is *the* core feature that everything else is built upon.
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...