5
\$\begingroup\$

I'm aware that in Unity, when you want to add (e.g.) a weapon to a character, you parent it to the "hand" bone of the character etc...

Well I'm trying to add a hat to a character in unity when it's clicked (and the head of the character is moving around beforehand), and I want the hat to always be in the same position on the characters head, no matter what position the (animated) head happens to be in when it's clicked.

I tried making a reference mesh in blender (just a cube), and then setting the hat mesh to the same position of that mesh in unity, and to do that I tried parenting it to the head bone and then positioning it on the exact spot of the head in the blender model, but I did this by using the "Child Of" restraints and apparently blender restraints don't render to unity.

SO I'm not sure if making a reference item in blender was the perfect solution, but how can I set the position of the hat to the same position on the characters head?

EDIT:

I'm using a basic CharacterController for the character, and basically my character starts as a capsule object with the CharacterController and then I hide the capsule mesh and make my .fbx model a child of the capsule, and when moving I only rotate the model, not the capsule (if that's relevant), but I (also) want to be able to place objects on NPCs that are moving around, and so far the way I'm making those is just adding a capsule collider to the .fbx and adding click events to it with event triggers... anyways here's the the node structure of the NPC model if that helps:

: enter image description here

the "teffilinBox" is the placeholder that I manually added after it imported to Unity, and it's what I was trying to get automatically by parenting with Blender, which didn't work.

BTW, I found another way to make meshes children of bones in blender, by going into pose mode and manually parenting the mesh to the bone, which WORKS in blener and it APPEARS to work in unity, although; the problem:

In blender, when you parent to a bone, it doesn't actually parent to the bone itself, it just weights it 100%, and it's actually a child of the armature only, with 100% weighting, so when I import it to unity, it doesn't recognize the parent-child relationship at all, but it still moves with the head so I guess it recognizes the weighting...

When I tried to make the hat object a child of the placeholder, it wasn't affected by the head at all, since in unity the placeholder itself isn't an actual child of the head, it just looks that way. And when I tried to parent the hat to the head, then just adjust the world position to that of the cube, it was always way off.

SO I just found a workaround that works, in case anyone else is having this problem: in Blender, when making the placeholder, just move to the first frame of the animation and position it but DON'T parent it to anything, then give it some unique name like "placeholder_Head" and then in Unity, on one of the start functions, find that gameobject (or ALL of the game objects that start with "placeholder" and then extract the other part of the name with Regex or something) and THEN parent it to the correct bone, in unity script, and afterwards, you can attach the hat object as a child of THAT, since now the placeholder is a real child of the bone. That worked for me, if anyone knows of how else to do it, I would like to know :) 'cause the main problem with this method is I'm not sure how to programmatically add all of the placeholders as children to the respective bone, because you can't just get a gameobject name with regex (Finding Game Object with Regular Expressions), without literally looping through all of the gameobjects or something like that... So does anyone know another way to do this (pretty basic) thing?

PS: to try to duplicate my issue to see what I mean, just get a rigged character in blender and try to make a placeholder cube or something then select the armature, go to pose mode and select the cube and shift-select the specific bone you want to parent it to, then make the animation and see how it moves with the bone in blender, but then import it to unity and try setting another object to the child of the placeholder with script any localPosition at 0, you'll see it doesn't work at all.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Are you using a rigidbody to move the character ? And can you give us a screenshot of your Unity character hierarchy ? \$\endgroup\$
    – Shashimee
    Aug 1, 2018 at 7:09
  • \$\begingroup\$ Hello! I noticed that you have asked a few questions here. Please consider revisiting them and mark as accepted those that helped you fix the issues you had, or at least vote on the the answers provided. \$\endgroup\$
    – Vaillancourt
    Nov 30, 2021 at 18:52

2 Answers 2

0
\$\begingroup\$

I ran into a similar problem, and I solved it this way: Every frame, take the bone's (in your case, the head bone's) transform, define an offset (from the center of the head, per se, to the top of the skull), and transform the bone's facing direction* with the offset applied (first). So:

public Vector3 boneToHat;    // from the start point of the bone to the origin of the hat

And in your update method:

Vector3 headTop = headBone.TransformPoint(boneToHat);
hat.position = headTop;

Then, you'll want to rotate the hat to be perpendicular to the head:

hat.up = headBone.forward;  // for instance, if the hat is oriented with *up* actually being up in Blender and the bone's forward is facing up

* My computer isn't booting right now, so I can't test, but using the forward property should work, if not that, click on the bone in the inspector and observe the colored line it's direction is aligned with, and use that axis (Blender can mess things up; this worked for me).

\$\endgroup\$
5
  • 1
    \$\begingroup\$ yeah but how do you get the offset in the first place, just programatically? It would be a lot easier to design the actual offset on the model somehow instead of just guessing positions \$\endgroup\$ Aug 6, 2018 at 17:01
  • \$\begingroup\$ @user2016831 Good point. You could A) create a hidden object in blender where the origin of the hat should be, B) move the 3D cursor to the location of the hat in Blender and calculate the offset from the bone that way, C) do trial and error until it looks good (hard code it). \$\endgroup\$
    – clabe45
    Aug 6, 2018 at 17:15
  • \$\begingroup\$ I wanted to make it as dynamic as possible for other pieces of clothing and otehr npcs etc. so I was thinking of making an empty in blender called "placeholders" and putting other empties as children of that and position each one where you want to clothing thing to be and then give each one the name of the exact name of the bone you want to parent to, then everythings nicely in the correct world position, except in blender nothing is parented, then in unity just programmatically set the parents of each empty to the bone which is they're name, any other ideas though? \$\endgroup\$ Aug 6, 2018 at 17:29
  • \$\begingroup\$ @user2016831 could you make the cloth empties children of the bones? \$\endgroup\$
    – clabe45
    Aug 6, 2018 at 17:43
  • \$\begingroup\$ not in blender, because it's not real "children" of bones in blender, it just weights it 100% to the bone, but when imported to unity it only ends up as a child of the armature and it's world position is all messed up, so that's why in unity I have to manually make it a child of the bone, unless there's a way to unweight the bone "children" once in unity and then just reparent them to pretend as if it was always parented the same \$\endgroup\$ Aug 6, 2018 at 21:51
0
\$\begingroup\$

Seems like the easiest approach would be to just put an empty game object at each spot you want to be able to attach stuff (eg top of the head), then set that game object as parent of the equipment at runtime. This way you're less reliant on the actual world position of the head, for example, when placing the hat.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ that's what I'm currently trying, except the problem is that it only works with the first frame of your animation and if you decide to use a different animation state for the beginning for whatever reason everything's messed up... but at least it kind of works, if there was a way to parent it in blender then completely unparent / unweight it in unity and re-parent it based on the original position that would be ideal seemingly \$\endgroup\$ Sep 5, 2018 at 2:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .