☑ Destroying the latest child created

Hello! New to the forums but i’ve been playing with playcanvas for a little while. Great job guys.

I am trying to write a function that will destroy a specified number of the latest children of an entity. I understand generically how to delete a child using:

var Child = _this.entity.children[2];
Child.destroy(); // delete child, all components and remove from hierarchy

I initially thought that when children are added to a parent they might be added to the end of the children array, and that I might be able to find the length of that array and run a for loop deleting them off the end as necessary. I’ve tried a few ways and I can’t seem to get it right.

My project: https://playcanvas.com/project/448794/overview/huxlo-sandbox. The function is inside of guiBox.js.

Does anyone have any ideas or starting points? Any help greatly appreciated.
Matt

As this.entity.children is an array, you can use pop() to remove the last element off the end?

e.g.

// Remove 3 children off the end
var child;
var children = this.entity.children;
for (var i = 0; i < 3 && children.length > 0; i += 1) {
    child = children.pop();
    child.destroy();
}

Or something along those lines.

Looking at the engine code, it does look like entity.addChild adds the child on the end of the array

        addChild: function (node) {
            if (node._parent !== null)
                throw new Error("GraphNode is already parented");

            this._children.push(node);
            this._onInsertChild(node);
        }

For just the last one added i think you can do this:
var children = this.entity.children;
this.children[this.children.length].destroy();

Thanks Steven, I hadn’t heard of pop() and this does the trick.

Matt

@ayrin: Close! Don’t forget Javascript arrays are 0 indexed so it actually be:

var children = this.entity.children;
children[children.length-1].destroy();

And you would still have to remove the array element as with the code above, you actually haven’t changed the size of the array :wink:

Just to explain what pop() does, it removes the last element of an array and also returns it which makes it useful for operations like your use case.

1 Like

@steven you are right :stuck_out_tongue: forgot that

Hi Steven,

I’m very close to the functionality that i’m trying to achieve but my function is a bit erratic and I cannot see why.

The general premise of my app is to model a modular building. The building is made up of 0.6m sections and so it can be made longer by adding 0.6m modules to it. However the “first” and “last” modules will stay the same so it is made longer by moving the “last module” and inserting “middle modules” before it. To make it smaller, the “last module” is moved back and “middle modules” are deleted.

The function is called when the “Length” is changed using a dat.GUI. The function is as follows.

GuiBox.prototype.setLength = function(){
    
    var l = Math.round(boxobj.Length/0.6)*0.6; // round length to nearest multiple of 0.6
    
    if (l != this.previousLength) {
        //move the last module
        var LastModulePos = new pc.Vec3(l - 0.6,boxobj.objy,boxobj.objz);
        _this.entity.findByName('LastModule').setLocalPosition(LastModulePos);
        
        //delete or insert modules into the middle
        if (l < this.previousLength) {

            var QTYtoDelete = (this.previousLength - l)/0.6;
            var children = _this.entity.children;
            var child;
            for (i = 0; i < QTYtoDelete && children.length > 3; i++) {
                child = children.pop();
                child.destroy();
                boxobj.numberOfModules = boxobj.numberOfModules - 1;
            }  
        }
        else {
            var QTYtoCreate = (l - this.previousLength)/0.6;
            var middleChild = _this.entity.findByName('MiddleModule');
            var clone;
            for (i = 0; i < QTYtoCreate; i++) { 
                clone = middleChild.clone();
                _this.entity.addChild(clone);
                var pos = new pc.Vec3(l - 1.2 - 0.6*i,boxobj.objy,boxobj.objz);
                clone.setLocalPosition(pos);
                boxobj.numberOfModules = boxobj.numberOfModules +1;
            }
        }
    }
    this.previousLength = l;
};

Any ideas why it doesn’t work as my logic thinks it should!?

Many thanks,
Matt

What is it currently doing compared to your expectation of what it should be doing?

When the “Length” is first increased from 1.8 no clones are made regardless of what Length it is increased to. Subsequent increases seem to work but then some decreases end in error. It’s hard to explain hence i’m having a tough time debugging.

Perhaps easiest to understand by playing with the length: https://playcanvas.com/editor/scene/487335/launch

Had a very quick as I’m a little swamped at the moment.

It does something wrong the first time because this.previousLength is undefined the very first time you add more pieces:

If you are not using the debugger already, I do recommend using it as it made this really easy to spot almost immediately: http://developer.playcanvas.com/en/user-manual/scripting/debugging/