Is something being called out of scope here?

I’m playing around with the ragdoll project @will put together to try and understand joints for another project I’m working on. As it stands, I’m getting an error saying joint.xform.getPosition() is not a function. The only reason for this I can think of is that joint.xform is being called out of scope, except in the original script it works fine.
Here’s the script with my changes:

var TestDoll = pc.createScript('testDoll');

// initialize code called once per entity
TestDoll.prototype.initialize = function() {
    //var graph = this.entity.model.model.graph;

    this.joints = [
        {
            bone: 'TorsoBone',
            body: 'Torso'
        },
        {
            bone: 'NeckBone',
            body: 'Head'
        },
        {
            bone: 'LShoulderBone',
            body: 'LeftArm'
        },
        {
            bone: 'LFunnyBone',
            body: 'LeftForeArm'
        },
        {
            bone: 'LWristBone',
            body: 'LeftHand'
        },
        {
            bone: 'RShoulderBone',
            body: 'RightArm'
        },
        {
            bone: 'RFunnyBone',
            body: 'RightForeArm'
        },
        {
            bone: 'RWristBone',
            body: 'RightHand'
        },
        {
            bone: 'RHipBone',
            body: 'RightUpperLeg'
        },
        {
            bone: 'RKneeBone',
            body: 'RightLowerLeg'
        },
        {
            bone: 'RAnkleBone',
            body: 'RightFoot'
        },
        {
            bone: 'LHipBone',
            body: 'LeftUpperLeg'
        },
        {
            bone: 'LKneeBone',
            body: 'LeftLowerLeg'
        },
        {
            bone: 'LAnkleBone',
            body: 'LeftFoot'
        }
    ];

    for (var i = 0; i < this.joints.length; i++) {
        var joint = this.joints[i];
        joint.bone = this.entity.findByName(joint.bone);
        joint.body = this.entity.findByName(joint.body);
        joint.initPos = joint.body.getPosition().clone();
        joint.initRot = joint.body.getRotation().clone();
        joint.xform = joint.body.findByTag('Bone');
    }

    /*
    for (var i = 0; i < parts.length; i++) {
        var part = parts[i];
        var e = new pc.Entity();
        e.addComponent('model', { type: 'sphere' });
        this.app.root.addChild(e);
        var partNode = this.entity.model.model.graph.findByName(part);
        e.setPosition(partNode.getPosition());
        e.setLocalScale(0.2, 0.2, 0.2);
    }*/
};

TestDoll.prototype.reset = function() {
    for (var i = 0; i < this.joints.length; i++) {
        var joint = this.joints[i];
        joint.body.rigidbody.teleport(joint.initPos, joint.initRot);
        joint.body.rigidbody.angularVelocity = pc.Vec3.ZERO;
        joint.body.rigidbody.linearVelocity = pc.Vec3.ZERO;
    }
};

// update code called every frame
TestDoll.prototype.update = function(dt) {
    var body = this.entity.findByName('Torso');
    if (body.getPosition().y < -30) {
        this.reset();
    }
    if (this.app.keyboard.wasPressed(pc.KEY_R)) {
        this.reset();
    }

    for (var i = 0; i < this.joints.length; i++) {
        var joint = this.joints[i];
        joint.bone.setPosition(joint.xform.getPosition()); //Error here
        joint.bone.setRotation(joint.xform.getRotation());
    }
};

Are there any entities with the name ‘Bone’ in the scene?

Yes, but they are on a different model than the one the script is attached to.

I think the joint.bone it’s referring to is the bone component within the joints array. So for joints[0] for example, joints.bone would be called ‘TorsoBone’.
I do have components tagged as ‘Bone’ which is why the joint.xform looks for the tag.

Only other thing I can think of is the bone components I have in the array now are the same entities tagged as ‘Bone’, and the original had the actual models bones as the array components.

Can you post a link to the project please? This is more of a scene setup issue rather than a script/coding issue.

Sure thing, it’s on the little dummy thing on the left:
https://playcanvas.com/editor/scene/595364

Nope, my bad, this is a script/code issue. findByTag returns an array of graphNodes with the tag https://developer.playcanvas.com/en/api/pc.Entity.html#findByTag

As a quick fix, since you know that only one entity will have the tag, you can change the line to:

        joint.xform = joint.body.findByTag('Bone')[0];

There are 14 entities with that tag.

Yes, but only one per body entity which is where you are calling findByTag from.

image