• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
Question by Fattie · Jun 17, 2012 at 01:04 PM · bonesskinnedmeshrendererskinned meshroot bone

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 not$$anonymous$$ng. It is a read-only value.

T$$anonymous$$s is a huge finding and we should all seriously thank Bunny83 for t$$anonymous$$s.

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


(Rephrasing t$$anonymous$$s 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!

alt text

exampSMRPanel.jpg (79.0 kB)
Comment
Bunny83
Emile-Swain

People who like this

2 Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · Jun 17, 2012 at 03:04 PM 0
Share

Once more ;) There is no root bone that is relevant for anything related to the SkinnedMeshRenderer. I admit i've never seen the "Root Bone" at the SkinnedMeshRenderer since our project uses Unity 3.0 and there is no such thing in the inspector.

I've just looked into the SkinnedMeshRenderer of Unity3.5 and found this:

 internal extern Transform actualRootBone
 {
     [WrapperlessIcall]
     [MethodImpl(MethodImplOptions.InternalCall)]
     get;
 }

It's an internal property which is used by the inspector to show you the root bone. As you can see it can't be set at all nor read since it's internal. I guess they implemented it to give you an easy access to the topmost bone. Anyway it's not related to the actual function of the SkinnedMeshRenderer.

edit the getter of that property is written in native code, but i guess it just does something like that:

 Transform root = bones[0];
 for(int i = 1; i < bones.Length; i++)
     if (root.IsChildOf(bones[i]))
         root = bones[i];
avatar image Bunny83 · Jun 17, 2012 at 03:30 PM 0
Share

It seems it has no function at all. Just try replacing it with something else. The bones are still the same. I guess you can replace it because Unity was lazy when writing the Inspector for the SkinnedMeshRenderer. They just use Serialized Properties for everything. So if you drag something onto the "rootbone" it serializes that information, but it's never used anywhere...

I can't look behind the scenes (just the managed part ;) ) this is just what you can observe and guess.

avatar image Fattie · Jun 17, 2012 at 03:41 PM 0
Share

".... It's an internal property which is used by the inspector to show you the root bone"

In Unity, what is the root bone? Is it the zero entry in .bones?

In short, when the inspector "gets" that informtaion ("to show you the root bone"), HOW DOES IT DO THAT?

Where does it look, to get that information !?!

2 Replies

· Add your reply
  • Sort: 
avatar image
Best Answer

Answer by Bunny83 · Jun 17, 2012 at 01:42 PM

I've posted it already on your other question as comment, but once more ;)

A SkinnedMeshRenderer doesn't have somet$$anonymous$$ng like a root bone. It doesn't even care about the bone-$$anonymous$$erarchy. The SkinnedMeshRenderer just needs an array with all bones in the order they are bound in the mesh. T$$anonymous$$s reference is setup by the Mesh importer. It creates the bone $$anonymous$$erarchy and assigns all bones to the bones array. In the Mesh a vertex can be bound to 4 different bones. The bones are specified by a bone-index. T$$anonymous$$s index is related to the bones array of the SkinnedMeshRenderer.

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

Another important array is the Mesh.bindposes - 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 w$$anonymous$$ch bone belongs to w$$anonymous$$ch 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 T$$anonymous$$gh
 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 T$$anonymous$$gh
 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 t$$anonymous$$s answer a bit longer x) )

Here's the $$anonymous$$erarchy of the bones, just as reference:

 Bone Hierarchy:
 Bip001
 |--Bip001 Footsteps
 |--Bip001 L Weapon
 |--Bip001 Pelvis
 |--|--Bip001 Spine
 |--|--|--Bip001 L T$$anonymous$$gh
 |--|--|--|--Bip001 L Calf
 |--|--|--|--|--Bip001 L Foot
 |--|--|--|--|--|--Bip001 L Toe0
 |--|--|--|--|--|--|--Bip001 L Toe0Nub
 |--|--|--Bip001 R T$$anonymous$$gh
 |--|--|--|--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 t$$anonymous$$s 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 + "\n";
     foreach (Transform T in aBone)
     {
         // Had to exclude other gameobjects since we have attached armor parts
         //Now only gameobjects are included that contains "Bip" ;)
         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[i].name + "\n";
     }
     text += "\nBone Hierarchy:\n";
     text += ProcessBone(RootBone,"");
     Debug.Log(text);    
 }

Comment
Fattie
Jessy
whydoidoit
Emile-Swain

People who like this

4 Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · Jun 17, 2012 at 03:35 PM 1
Share

Ok, when you import a skinned mesh, the importer generates a Mesh asset and the corresponding bone hierarchy which it extracts from the FBX file. The importer automatically links up everything that belongs to each other. The renderer needs the complete list of bones in the exact order they have been specified.

This sounds like you have a real human arm and expect some kind of sub-D socket somewhere to plug in another arm. ;) The bones belong to the skin (Mesh).

avatar image Fattie · Jun 18, 2012 at 06:11 AM 0
Share

Totally understood ... in short ..

"[the root bone display in the inspector is] ... is used by the inspector to show you the root bone"

Quite simply, in Unity, what is the root bone?

For example: is it the zero entry in .bones? (That is a wild guess, perhaps irrelevant.)

In short, when the inspector "gets" that informtaion ("to show you the root bone"), how does it do that?

avatar image Bunny83 · Jun 18, 2012 at 09:19 AM 2
Share

Well, we don't know how Unity gets the root bone or if it's storing them somewhere. The property calls a native code function, so we can't see what it does, if it will cache it somewhere or not. Usually the root bone is the topmost bone when they are arranged in a hierarchy. So i would give it two criteria: It has to be a bone of that Renderer (have to be in the bones array) and doesn't have another bone as parent. That what my little code snippet does in my first comment on your question ;)

I know you don't like reading, so here's it again ;) Keep in mind, that's what i think how it works:

 Transform root = bones[0];
 for(int i = 1; i < bones.Length; i++)
     if (root.IsChildOf(bones[i]))
         root = bones[i];
avatar image Fattie · Jun 18, 2012 at 11:16 AM 0
Share

Hmm ...

have you noticed: I may be mistaken, but say you import a model, and it has a dozen or so bones. In fact, look at the example image I posted, you can see there are ten bones or so shown in the Hierarchy panel.

Note that, they appear to be in there somewhat "randomly" ... it's NOT the case that there is one highest bone with all below them in "folders". Indeed in that example the root bone has many siblings.

Perhaps I am mistaken in this ... what do you think ?

To repeat, it would appear that in terms of "the Hierarchy window, ie, the transform.parent relationships", that hierarchy (ie "the transform.parent relationship chain") is in fact NOT repeat NOT actually "the real hierarchy" of the bones ... or at any rate .. the root appears to sometimes have siblings randomly, etc

What do you think?

thus, for example, it's easy enough to make up yer own bones, and in Unity you can load them in it would apear SkinnedMeshRenderer.bones, set the boneWeights and indeed bindposes correctly on the mesh (whilst you set your uv, etc) ........ all very well BUT how or where do you set the root bone in that process?

or in fact just as you say, is it "just there" i.e. i's no big deal, what I mean is -- YOU DO NOT HAVE TO LET THE RENDER, OR ANYTHING ELSE "KNOW" -- what your "root" bone is, is that correct?

(ie, precisely as you say, one's root bone, I guess you could figure it out by noticing which one of your bones has no parent ... but in fact, again, you don't have to "tell anyone" which bone that is.

If, for some reason in your own software, you needed to use the concept of the "root" bone a lot, you'd of course just store it your own way (perhaps just what the inspector involved is doing.)

(If that is the case, the fact that the Inspector importantly Annonces which bone is the root bone with neon lights is, sort of silly and pointless. Who gives a stuff which is the root bone? How would you use that for anything anyway?)

What do you think ??

avatar image Fattie · Jun 18, 2012 at 11:20 AM 0
Share

Another way to look at this:

in fact, does the transform.parent hierarchy (ie, the hierarhy one sees every day in the "Hierarchy" Apple-4 window*) ... does the transform.parent hierarchy have any relationship to the bone hierarchy?*

Or are they totally irrelevant to each other?

That is perhaps the basic question here. :-O

(To make an analogy .. a bit like when you make a hinge, the object hinged to the hingeholder object, is, often, also a child (ie, transform.parent hierarchy) of that hinge -- and that may or may not work for or against you in specific situations, but, there is absolutely no need for the two things to be true together.)

Thanks !!

  • which, incidentally, you can resize beautifully using THIS! http://answers.unity3d.com/questions/267097/editor-programming-experts-regarding-layouts.html

avatar image

Answer by Shinobubu · Apr 17, 2013 at 01:06 AM

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

Comment

People who like this

0 Show 0 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Skinned Mesh Renderer -> Root Bone 1 Answer

Can we get skinnedMeshRender.bones in unity source after choose optimize game object? 0 Answers

Are Joints in fact Transforms? 2 Answers

Does the transform.parent hierarchy have any relationship to the bone hierarchy? 1 Answer

Attach one animated mesh to another 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges