Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

unity assign position of child object to another after setting it's parent

Discussion in 'Scripting' started by yaakovyitzchakbenmoshe, Aug 1, 2018.

  1. yaakovyitzchakbenmoshe

    yaakovyitzchakbenmoshe

    Joined:
    Feb 9, 2018
    Posts:
    21
    Hi,

    I'm trying to make a character with items attachable to it, like a hat, handheld things etc.

    I've heard the way to do this is, in the 3D model editing program, create an empty object or cube and parent it to the hand / head bone and then position it correctly, and then in unity "snap" the mesh item (hat etc.) to the empty.

    I was trying to accomplish this by setting the item gameobject as a parent to the desired bone, so it will automatically follow it, and then, to position it correctly, set the transform.position to the transform.position of the reference object (which is just a gameobject when imported to unity).

    But for some reason, although it is parenting to the correct bone, but when I set the position afterwards (and even before!) to the reference gameobject, the position is always way off, so I'm not sure how to do it. Here's the code:

    Code (CSharp):
    1. GameObject teffilinGuy = GameObject.Find("otherCharacter");
    2.         GameObject teffilinGuyCube = GameObject.Find("Cube1");
    3.         GameObject teffilinCube = GameObject.Find("teffilinBox");
    4.         if (teffilinGuy != null)
    5.         {
    6.             print("found him! ");
    7.             EventHelper.addEventToThing(teffilinGuy, EventTriggerType.PointerClick, () =>
    8.             {
    9.                 print("teffilined");
    10.                 teffilinGuy.GetComponent<Animator>().SetBool("clicked", true);
    11.                 teffilinCube.transform.position = teffilinGuyCube.transform.position;
    12.                 teffilinCube.transform.SetParent(GameObject.Find("Head").transform, true);
    13.                 teffilinCube.transform.position = teffilinGuyCube.transform.position;
    14.  
    15.  
    16.             });
    17.         }
    and here is the node setup of the gameobjects for the character:
     
  2. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,559
    Aren't you meant to change transform.localPosition, instead (global) transform.position ?

    Just wonder, but hope you don't run GameObject.Find every frame, or so?
    Also, if you got for example try GameObject.Find ( objectName ), and you have more than one object with same name, you may get incorrect one.
     
  3. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    1,315
    I think you've misinterpreted the technique somewhat. By "snapping" the object to the empty, you are meant to parent the item to that empty.

    The empty is first parented to the Head (let's say). Then your item gets parented to the empty, and not the Head. The localPosition for the item should be (0,0,0).
     
  4. yaakovyitzchakbenmoshe

    yaakovyitzchakbenmoshe

    Joined:
    Feb 9, 2018
    Posts:
    21
    thanks, brilliant -- that's exactly what I was wondering what to do :)
     
  5. yaakovyitzchakbenmoshe

    yaakovyitzchakbenmoshe

    Joined:
    Feb 9, 2018
    Posts:
    21
    thanks for the tips, I was just getting the game objects in a sloppy way just for testing
     
  6. yaakovyitzchakbenmoshe

    yaakovyitzchakbenmoshe

    Joined:
    Feb 9, 2018
    Posts:
    21

    Actually I just tried it, and it's a good theory, except it doesn't work in my case.

    Maybe I sjould have mentioned, when I made the empty, it was in blender: I entered pose mode and selected the cube/empty/whatever and then shift clicked the head bone and parented, and technically IT is parented to the bone, but I don't think unity recognizes at as parented to the bone at all, it just appears to be in the armature node (see node picture above) and when I add anything else as a child to it, it doesn't act as if it's a child of it at all, it doesn't move with the animation etc. & localPosition = Vector.zero doesn't move it anywhere close to it. Is this a blender problem? How can I parent the empty correctly to serve as a reference?
     
  7. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,186
    If it's parented to the Head, it will move with Head bone, unless you have keyframes that makes it stick in place.

    Try manually putting the hat as a child of your "teffilinBox" object in the editor, and set it's local position to 0,0,0. Check if it moves correctly.
     
  8. yaakovyitzchakbenmoshe

    yaakovyitzchakbenmoshe

    Joined:
    Feb 9, 2018
    Posts:
    21
    Thanks, but it didn't exactly work.

    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 :)

    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.