Get so-called "root bone" using Unityscript/c#

Note - critically, Bunny has determined that changing the field in question in the inspector, is meaningless, just an error on Unity’s part. Changing that field in the inspector actually does absolutely nothing. It is a read-only value.

This is a huge finding and we should all seriously thank Bunny83 for this.

Anther triumph of the rare smart user v. utterly useless indeed missing documentation.


(Rephrasing this slightly…)

If you look in the Inspector at your SkinnedMeshRenderer, you will see the #7 item (just after Mesh and just before Bounds) is “RootBone”

Can anyone please state, using either Unityscript or c#, how to get what the Panel there refers to as the “Root Bone” of that object? As shown in the image below with red arrows. Thanks!!

As Bunny, thank God, absolutely precisely explains …

"In [a] Mesh, a vertex can be bound to four different bones…

The bones are specified by a bone-index…

[from] the bones array of the SkinnedMeshRenderer…

[ie, the array SkinnedMeshRenderer.bones]"

So, WTF is the “Root Bone”??

Is it the 0 element of SkinnedMeshRenderer.bones, or is that naif, or what? THANKS!

I’ve posted it already on your other question as comment, but once more :wink:

A SkinnedMeshRenderer doesn’t have something like a root bone. It doesn’t even care about the bone-hierarchy. The SkinnedMeshRenderer just needs an array with all bones in the order they are bound in the mesh. This reference is setup by the Mesh importer. It creates the bone hierarchy and assigns all bones to the [bones array][1]. In the Mesh a vertex can be bound to 4 different bones. The bones are specified by a bone-index. This index is related to the bones array of the SkinnedMeshRenderer.

Again, the bone-hierarchy is irrelevant for the SkinnedMeshRenderer. The hierarchy is just an automatic way for affecting subbones, but on the skinning level there are just bones.

Another important array is the [Mesh.bindposes][2] - array. It specifies the “resting position” of each bone. The example shows how to create a very very simple model with two bones.

It’s almost impossible to “simply” assign a bone structure to a certain skinned mesh because you have no idea of the bones order. You can of course try to determine which bone belongs to which index by calculating the mean of all vertices that are affected by a bone. That usually gives you the approximate position of the bone, but it’s not really reliable.

For imported models, the connection - information is imported by the MeshImporter and is stored in the bones array.

edit

Here’s an example print of our player characters bone array:

Bone index:0  Name: Bip001 R Thigh
Bone index:1  Name: Bip001
Bone index:2  Name: Bip001 R Calf
Bone index:3  Name: Bip001 R Foot
Bone index:4  Name: Bip001 L Foot
Bone index:5  Name: Bip001 R Toe0
Bone index:6  Name: Bip001 Pelvis
Bone index:7  Name: Bip001 Spine
Bone index:8  Name: Bip001 Spine1
Bone index:9  Name: Bip001 L Thigh
Bone index:10  Name: Bip001 R UpperArm
Bone index:11  Name: Bip001 R Forearm
Bone index:12  Name: Bip001 R ForeTwist
Bone index:13  Name: Bip001 RUpArmTwist
Bone index:14  Name: Bip001 R Hand
Bone index:15  Name: Bip001 R Finger0
Bone index:16  Name: Bip001 R Finger2
Bone index:17  Name: Bip001 R Finger1
Bone index:18  Name: Bip001 R Finger01
Bone index:19  Name: Bip001 R Finger21
Bone index:20  Name: Bip001 R Finger11
Bone index:21  Name: Bip001 R Clavicle
Bone index:22  Name: Bip001 Neck
Bone index:23  Name: Bip001 Head
Bone index:24  Name: Bip001 L Clavicle
Bone index:25  Name: Bip001 Jaw
Bone index:26  Name: Bip001 L Calf
Bone index:27  Name: Bip001 L Toe0
Bone index:28  Name: Bip001 L UpperArm
Bone index:29  Name: Bip001 L Forearm
Bone index:30  Name: Bip001 L ForeTwist
Bone index:31  Name: Bip001 LUpArmTwist
Bone index:32  Name: Bip001 L Hand
Bone index:33  Name: Bip001 L Finger0
Bone index:34  Name: Bip001 L Finger2
Bone index:35  Name: Bip001 L Finger1
Bone index:36  Name: Bip001 L Finger01
Bone index:37  Name: Bip001 L Finger21
Bone index:38  Name: Bip001 L Finger11

As you can see the first bone isn’t the root bone (Bip001). It conpletely depends on how the model has been created and how the modelling software has exported the bones.

There is no general rul how you “usually” add bones to the array. It doesn’t matter, it’s just important that they are in the same order you used in your Mesh.

edit: (Let’s make this answer a bit longer x) )

Here’s the hierarchy of the bones, just as reference:

Bone Hierarchy:
Bip001
|--Bip001 Footsteps
|--Bip001 L Weapon
|--Bip001 Pelvis
|--|--Bip001 Spine
|--|--|--Bip001 L Thigh
|--|--|--|--Bip001 L Calf
|--|--|--|--|--Bip001 L Foot
|--|--|--|--|--|--Bip001 L Toe0
|--|--|--|--|--|--|--Bip001 L Toe0Nub
|--|--|--Bip001 R Thigh
|--|--|--|--Bip001 R Calf
|--|--|--|--|--Bip001 R Foot
|--|--|--|--|--|--Bip001 R Toe0
|--|--|--|--|--|--|--Bip001 R Toe0Nub
|--|--|--Bip001 Spine1
|--|--|--|--Bip001 Neck
|--|--|--|--|--Bip001 Head
|--|--|--|--|--|--Bip001 HeadNub
|--|--|--|--|--|--Bip001 Jaw
|--|--|--|--|--|--|--Bip001 Xtra01Nub
|--|--|--|--|--Bip001 L Clavicle
|--|--|--|--|--|--Bip001 L UpperArm
|--|--|--|--|--|--|--Bip001 L Forearm
|--|--|--|--|--|--|--|--Bip001 L Hand
|--|--|--|--|--|--|--|--|--Bip001 L Finger0
|--|--|--|--|--|--|--|--|--|--Bip001 L Finger01
|--|--|--|--|--|--|--|--|--|--|--Bip001 L Finger0Nub
|--|--|--|--|--|--|--|--|--Bip001 L Finger1
|--|--|--|--|--|--|--|--|--|--Bip001 L Finger11
|--|--|--|--|--|--|--|--|--|--|--Bip001 L Finger1Nub
|--|--|--|--|--|--|--|--|--Bip001 L Finger2
|--|--|--|--|--|--|--|--|--|--Bip001 L Finger21
|--|--|--|--|--|--|--|--|--|--|--Bip001 L Finger2Nub
|--|--|--|--|--|--|--Bip001 L ForeTwist
|--|--|--|--|--|--Bip001 LUpArmTwist
|--|--|--|--|--|--|--Bip001 L Shoulder
|--|--|--|--|--Bip001 R Clavicle
|--|--|--|--|--|--Bip001 R UpperArm
|--|--|--|--|--|--|--Bip001 R Forearm
|--|--|--|--|--|--|--|--Bip001 R Hand
|--|--|--|--|--|--|--|--|--Bip001 R Finger0
|--|--|--|--|--|--|--|--|--|--Bip001 R Finger01
|--|--|--|--|--|--|--|--|--|--|--Bip001 R Finger0Nub
|--|--|--|--|--|--|--|--|--Bip001 R Finger1
|--|--|--|--|--|--|--|--|--|--Bip001 R Finger11
|--|--|--|--|--|--|--|--|--|--|--Bip001 R Finger1Nub
|--|--|--|--|--|--|--|--|--Bip001 R Finger2
|--|--|--|--|--|--|--|--|--|--Bip001 R Finger21
|--|--|--|--|--|--|--|--|--|--|--Bip001 R Finger2Nub
|--|--|--|--|--|--|--Bip001 R ForeTwist
|--|--|--|--|--|--Bip001 RUpArmTwist
|--|--|--|--|--|--|--Bip001 R Shoulder
|--Bip001 R Weapon

I’ve used this little script:

public SkinnedMeshRenderer R; // assign in the inspector
public Transform RootBone;    // assign in the inspector

string ProcessBone(Transform aBone, string indent)
{
	string result = indent + aBone.name + "

“;
foreach (Transform T in aBone)
{
// Had to exclude other gameobjects since we have attached armor parts
//Now only gameobjects are included that contains “Bip” :wink:
if (T.name.Contains(“Bip”))
result += ProcessBone(T,indent+”|–");
}
return result;
}

void Start ()
{
	Transform[] bones = R.bones;
	string text = "Bone array:";
	for(int i = 0; i < bones.Length; i++)
	{
		text += "Bone index:"+i+"  Name: "+bones*.name + "

";*

  •   }*
    
  •   text += "
    

Bone Hierarchy:
";*

To simulate Segment Bone scaling compensation all the bones in my rig are not parented to each other (floating non hierarchy transforms) and it works just fine. Rootbone is none utilizable.