Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • 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
1
Question by jheffel · Aug 03, 2011 at 10:44 PM · hierarchyfindbonerecursion

How to get a recursive named bone transform?

Hi I'm trying to get the transform of a hand bone that is deep in the bone hierarchy. I've tried many different ways to access it but haven't found one that works yet.

It tried writing this function to go through all of the bones but it seems to only grab the immediate children of the root bone.

 function findBone(parent: Transform) : Transform{
     for(var child : Transform in parent){
         print("Found bone: " + child.name);
         if (child.name == "CharacterSkeleton R Hand"){
             return child;
         }
     }
 }


I have also tried putting in the path to get the specific hand bone. Is this not working because there are spaces in the bone names?

 Handbone = Character.transform.Find("CharacterSkeleton/CharacterSkeleton Pelvis/CharacterSkeleton Spine/CharacterSkeleton Spine1/CharacterSkeleton Spine2/CharacterSkeleton Spine3/CharacterSkeleton Neck/CharacterSkeleton R Clavicle/CharacterSkeleton R UpperArm/CharacterSkeleton R Forearm/CharacterSkeleton R Hand").transform;

in both cases I get a nullReferenceException on this line:

 HandLoc.position = HandBone.position;

Where I am guessing HandBone.position is null.

Here is the script in its entirety:

 private var HandBone : Transform;
 private var HandLoc : Transform;
 private var RootBone : Transform;
 private var SeatLoc : Transform;
 var Character : GameObject;
 
 Debug.Log("Using Character: " + Character.name);
 RootBone = Character.transform.FindChild("CharacterSkeleton").transform;
 Handbone = Character.transform.Find("CharacterSkeleton/CharacterSkeleton Pelvis/CharacterSkeleton Spine/CharacterSkeleton Spine1/CharacterSkeleton Spine2/CharacterSkeleton Spine3/CharacterSkeleton Neck/CharacterSkeleton R Clavicle/CharacterSkeleton R UpperArm/CharacterSkeleton R Forearm/CharacterSkeleton R Hand").transform;
 //Handbone = findBone(RootBone);
 
 SeatLoc = transform.FindChild("ChairSeat").transform;
 HandLoc = transform.FindChild("ChairHand").transform;
 
 function Update (){
 
     SeatLoc.position = RootBone.position;
     HandLoc.position = HandBone.position;
 } 
 
 function findBone(parent: Transform) : Transform{
     for(var child : Transform in parent){
         print("Found bone: " + child.name);
         if (child.name == "CharacterSkeleton R Hand"){
             return child;
         }
     }
 }

If I comment out all of the hand code, the RootBone code works perfectly. Any ideas on how to access the hand bone?

Comment
Add comment · 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 jheffel · Aug 03, 2011 at 11:30 PM 0
Share

also a side note, what is the correct usage of something like this:

SeatLoc = transform.FindChild("ChairSeat").transform; OR SeatLoc = transform.FindChild("ChairSeat");

It doesnt appear to have an effect if I keep the transform at the end or if I remove it.

avatar image Graham-Dunnett ♦♦ · Aug 04, 2011 at 09:37 AM 0
Share

You should recursively call your findBone() function. Inside the function once you have a child call findBone(child) so you search down the tree.

avatar image Graham-Dunnett ♦♦ · Aug 04, 2011 at 09:41 AM 0
Share

oh, and the transfrom.find() is relative to the current bone, so take a look at what the name of your Character.transform is, and make sure that does not appear in the path that you are searching for.

3 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by sneftel · Aug 04, 2011 at 01:32 PM

If Handbone = Character.transform.Find("...").transform itself isn't giving you a NullReferenceException due to accessing the transform property, then you're finding the hand bone correctly. My guess is that it's the chair you're not finding.

Comment
Add comment · Show 3 · 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 jheffel · Aug 04, 2011 at 03:10 PM 0
Share

I thought this might be the case as well, but right before the update function i tried putting these debugs:

Debug.Log("SeatLoc.position = " + SeatLoc.position); Debug.Log("HandLoc.position = " + HandLoc.position); Debug.Log("RootBone.position = " + RootBone.position); Debug.Log("HandBone.position = " + HandBone.position);

and it prints out the position of all of them except the HandBone.position which gives another NullReferenceException

avatar image sneftel · Aug 04, 2011 at 03:18 PM 0
Share

Probably because you capitalized HandBone differently than when you set it.

avatar image jheffel · Aug 04, 2011 at 04:12 PM 0
Share

lol, I thought I had fixed all of those capitalization mistakes, except i missed the most important one. Now my recursive function and the bone 'path' are both working

I will post my new recursive function as an answer for those interested

avatar image
3

Answer by Heiko · Aug 04, 2011 at 03:53 PM

You are missing the recursive step, in C# it would be like this:

 public Transform SearchHierarchyForBone(Transform current, string name)   
 {
     // check if the current bone is the bone we're looking for, if so return it
     if (current.name == name)
         return current;

     // search through child bones for the bone we're looking for
     for (int i = 0; i < current.GetChildCount(); ++i)
     {
         // the recursive step; repeat the search one step deeper in the hierarchy
         Transform found = SearchHierarchyForbone(current.GetChild(i), name);

         // a transform was returned by the search above that is not null,
         // it must be the bone we're looking for
         if (found != null)
             return found;
     }
 
     // bone with name was not found
     return null;
 }
Comment
Add comment · Show 2 · 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 zuja · Jun 10, 2012 at 01:49 PM 0
Share

Little addition: if (current.name == name) --> if (current.name.Contains(name)) A Bip often has extra info in the name, so this method helps you to work more generic.

avatar image inewland · Jun 18, 2013 at 07:42 PM 0
Share

Bravo sir!

avatar image
1

Answer by jheffel · Aug 04, 2011 at 04:15 PM

here is the fixed recursive function for those interested, I had capitalization mistakes on the HandBone variable, and now both methods work.

 function findBone(parent: Transform) : Transform{
     for(var child : Transform in parent){
     
         print(parent.name + " found bone: " + child.name);
         
         if (child.name == "CharacterSkeleton R Hand"){
             Debug.Log("Found Hand, final return");
             return child;
         }
         else{
             var tempchild : Transform = findBone(child);
             Debug.Log("current bone: " + child.name + ", tempchild: " + tempchild.name);
             //if(tempchild.name != child.name){
             
                 if(tempchild.name == "CharacterSkeleton R Hand"){
                     Debug.Log("Found Hand, return to parent");
                     return tempchild;
                 }
             //}
             else{
             Debug.Log("Didnt find hand, returning to parent: " + parent);
                 //return parent;
             }
             
         }
         
     }
     return parent;
 }
Comment
Add comment · 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.

Follow this Question

Answers Answers and Comments

6 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How do i find a bone on my character within a script? 2 Answers

find next gameobject in hierarchy? 1 Answer

Adding extra bones to an already imported and prefab'ed character. 1 Answer

How can I find a unique sibling/parent/child in a specific hierarchy and not from all the scene? 1 Answer

Adding new bones to a character 1 Answer


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