Search Unity

"stitch multiple body parts into one character"

Discussion in 'Scripting' started by masterprompt, Jan 6, 2009.

  1. nitoh

    nitoh

    Joined:
    Mar 20, 2014
    Posts:
    30
    Hello everyone!

    My question is if anyone can translate the script to PLAYMAKER Action?
    Fufurata1234 has done it, but the file is lost. It would be a great help!
    Thank you very much!
     
  2. Ramsdal

    Ramsdal

    Joined:
    Oct 18, 2013
    Posts:
    251
    @masterprompt Any progress on the project? ;)
     
    Last edited: Apr 2, 2015
  3. MrChrisso

    MrChrisso

    Joined:
    Mar 10, 2015
    Posts:
    1
    Very helpful! I've got this working and this is probably the approach I'll use on my project. I'm just wondering though, what's wrong with just using submeshes for the character that you just turn on and off as needed?
     
  4. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    5,684
    It's probably just a matter of how many submeshes you would have. If it's very few, then no problem.
     
  5. masterprompt

    masterprompt

    Joined:
    Jan 6, 2009
    Posts:
    115
    Sorry, I've lost a lot of time with Unity crashing over the last few months. I'm running on a constant crunch until the end of the month. I'll revisit closer to the end of the month and throw this together for everyone. Sorry for the delay.
     
    IgorAherne, Ramsdal and theANMATOR2b like this.
  6. masterprompt

    masterprompt

    Joined:
    Jan 6, 2009
    Posts:
    115
    Finally got around to getting this done :)
    Not entirely sure if this is what you need but here it is!
     
  7. Ramsdal

    Ramsdal

    Joined:
    Oct 18, 2013
    Posts:
    251
    @masterprompt thanks! I will be having a look at it and hope it solves some issues. Thanks again! :)
     
  8. YoungDeveloper

    YoungDeveloper

    Joined:
    Jun 28, 2013
    Posts:
    65
    Yes, guilty, grave digging at all it's glory.

    I must say huge thanks to @masterprompt for providing such awesome examples.

    I made some test with the example, at the end mostly rewrote it, but here are couple notes.
    You dont actually need whole rig - skeleton for each part, you can have only the parts you need.
    For example if you add shoe and for moving it can contain 2 bones then its all you need to attach it. Full rig is only on the main character itself.

    But the core question stays, do you actually need those bones for each separate part.
    Are any known ways to attach mesh who doesn't have any animations or bones, glove for example.
     
    Last edited: Jun 28, 2015
    homemacai likes this.
  9. pahe

    pahe

    Joined:
    May 10, 2011
    Posts:
    543
    @YoungDeveloper
    We're creating a model that way and the only one that keeps its skeleton is the head model. But this is the full skeleton of the whole character.
    If I remember correctly you have to keep the skeleton structure for all merged models that should be animated later, else you would get an animation error like: "animation does not match bind poses" or something like that.

    Our code is nearly 2 years old, maybe something has changed, but I doubt that. Would be interesting if you could enlargen your skeleton piece by piece all the time though.
     
  10. YoungDeveloper

    YoungDeveloper

    Joined:
    Jun 28, 2013
    Posts:
    65
    @pahe So only the head contains the skeleton, but you still have to keep the structure of the bones for each part, what do you mean by structure?
    Friend on another forum suggested that i should use bone weight, and no bones are needed at all, only for the main mesh itself

    If that is possible, that would mean that the character and the glove has to be perfectly aligned before 'attaching', like in a T pose?
    I just don't understand how can you tell vertexes bind to something without knowing which vertex are what.

    I made a quick demonstration to illustrate the the idea.

    Humanoid contains mesh with the animator, which contains all of the rig. And i have a glove which is simply a mesh, without any bones or animations.
    Is it possible to 'wear' it in such case?

    I did succeed wearing it, if glove contains a copy of the hand part bones (starting from wrist), but it would be cool to not have any bone data on each separate part.
     
    Last edited: Jun 29, 2015
  11. pahe

    pahe

    Joined:
    May 10, 2011
    Posts:
    543
    @YoungDeveloper
    Afaik it won't work without bones structure for your glove. The SkinnedMeshRenderer depends on the bone structure, that it is present for your glove otherwise it won't render/animate it (at least not for us).

    Here's the overwiew how it is done for our character:
    1. Model the whole character with all parts in Maya.
    2. Animate all models.
    3. Export each part seperately.
    4. In Unity, stitch all parts together by taking each part and combining them together into one mesh. Build one skeleton hierarchy and add it to the SkinnedMeshRenderer.

    As I said, the bones structure must be the same as used in the animation (so, if you have a different bone hierarchy for your glove, maybe you have to adjust your bones there).
     
    theANMATOR2b likes this.
  12. specterdragon

    specterdragon

    Joined:
    Dec 30, 2013
    Posts:
    21
    And 6 years later, this is still a great thread!
    Ported the original code to C# in Unity 5, restructured it for what I need, and it just works!

    I'm wondering, has anyone found any way to make this more efficient? Sifting through the whole bone structure can be time consuming. On my non-standard biped, I have 46 bones (and expect more once I have control bones in place). Running through the full skeleton and matching it up to the parent takes about 12 seconds (yikes!). Breaking the attachment into multiple prefabs with a small number of bones as suggested by @YoungDeveloper helps (attaching them one at a time), but sometimes that isn't possible depending on the model (female dress, for example, that's influenced by a fair number of bones).
     
  13. specterdragon

    specterdragon

    Joined:
    Dec 30, 2013
    Posts:
    21
    Replying to my own question :D LOL

    For anyone else with the same troubles, I found what seems like an easy solution. I attached the original script to what will become the parent object. I added a dictionary to the class with a recursive function to get a list of the progeny transforms and associate them to their names. Then during the bone lookup, rather than searching through all of the parent bones for each child bone, it's a simple lookup table that already contains the transforms.

    Code (csharp):
    1.  
    2.     Dictionary<string, Transform> tree = new Dictionary<string, Transform>();
    3.  
    4.     void Start(){
    5.         CatalogChildren(transform);
    6.     }
    7.  
    8.     void CatalogChildren(Transform obj){
    9.         tree.Add (obj.name, obj.transform);
    10.         foreach(Transform child in obj)
    11.             CatalogChildren(child);
    12.     }
    13.  
    14. // in ProcessedBonedObject()
    15. ...
    16.         /*      Assemble Bone Structure     */
    17.         Transform[] MyBones = new Transform[ ThisRenderer.bones.Length ];
    18.         for ( var i=0; i<ThisRenderer.bones.Length; i++ )
    19.             MyBones[i] = tree[ThisRenderer.bones[ i ].name];
    20.  
    This also removes the need for the FindChildByName() method.
     
    theANMATOR2b likes this.
  14. YoungDeveloper

    YoungDeveloper

    Joined:
    Jun 28, 2013
    Posts:
    65
    I took a look at how Bethesda software did it for Skyrim. They have their own editor, and new bone set is attach to every new item (not whole rig). But it makes sense, some of the items are similar of course, so weights will be the same, but some items are quite different, with expanding scale armor and other features. So direct weight copy will not produce needed results.
    They do most of the part use same imported weights and then manipulate them slightly if needed i the editor, so the process is quite fast.
     
  15. masterprompt

    masterprompt

    Joined:
    Jan 6, 2009
    Posts:
    115
    I did something very similar in the final version of PlayTown (where we needed avatar clothing). I only created this simple project as a means of showing concept, optimization was out of the scope. Thanks for helping show there is room for improvement for those up for the task :)
     
  16. Vit3D

    Vit3D

    Joined:
    May 2, 2015
    Posts:
    64
    masterprompt, many thanks!

    I very interested in combining character from parts (main body + clothes) . I downloaded and tested ModelStitching example and it works fine with my character models. There is only one "minus" for my needs -- this example made only temporary changes and scene return to initial state (no clothes) after I stop playing.
    Unfortunately I have very small knowledge in codding (I'm character creator) so I'd like to ask --
    Is it possible to merge avatar and clothes permanently using Stitcher script, so after running it once I will have character with clothes in the scene?
    As I understand Stitcher.cs is not MonoBehaviour type, so I'm not able to run it directly and Tester.cs used to call it.
    So what script should be used to make permanent scene changes I described above?

    Looking forward for Your answer.

    Cheers,
    Vit
     
  17. Vit3D

    Vit3D

    Joined:
    May 2, 2015
    Posts:
    64
    I found the trick how to keep permanent copy of merged character+clothes version:
    - Before starting play I created empty prefab object in my Assets folder;
    - Both character and clothes model have no animation at all, just plain T-Pose;
    - Then I start play and select corresponding add clothes button; avatar in scene successfully modified and now have character+clothes;
    - Still in play mode I drag modified character from scene on my prefab in Assets folder;
    - I stop play mode (all changes in scene disappear).
    If then I drag just created prefab in the scene, it has both character and clothes and can be successfully animated.
    The only issue I found -- prefab does not have material information for cloth part and it should be assigned manually.

    Is it possible to automate the steps I described by some script?

    Cheers,
    Vit
     
  18. masterprompt

    masterprompt

    Joined:
    Jan 6, 2009
    Posts:
    115
    It is possible. You would need someone to create a script that can be executed in the editor (rather than merely during game runtime). Because the scripts provided aren't of Monobehaviour, it means they can don't need to be part of a GameObject to be used, they can be used by themselves. I know that probably doesn't make a lot of sense if your coding abilities aren't high enough to create Editor tools (no offense intended). Just know it is possible using the provided classes.
     
  19. Vit3D

    Vit3D

    Joined:
    May 2, 2015
    Posts:
    64
    @masterprompt, Many thanks for reply!
    I managed to make script (based on Your script) which can do this.
    As I told, I have low experience in codding, but it works fine with my characters.
     
    Last edited: Oct 8, 2015
  20. robahouston

    robahouston

    Joined:
    Jul 3, 2012
    Posts:
    16
    @masterprompt Let me start off with this, this entire thread has been really amazing!

    I don't think I completely understand what is going on with the script. I am strictly an artist, though recently I have been dipping my toes into the coding pool. Sadly I do not think I have the mind for it and frankly, the art pool is massive enough at the moment. Having said that, my model is 6 separate pieces. 2 arms, legs etc. My player character can change their armor on all of these pieces respectively. My questions are as follows:

    Q1: When they do this they change both arms. Does this code replace the mesh of the original arms with the new arm mesh?
    Q2: Do I need to export the entire bone rig with the arms or can I just export the skinning information without the mesh?
    Q3: Is trying something ridiculously ludicrous?

    My hope is to have a single skeleton in unity and the code will simply apply the correct mesh based on player selection from a menu. When they select a new head, the current head should be removed and replaced with a completely different mesh.

    Example:
    Player Skeleton Rig
    Head 1 >> Head 2
    Torso 15
    Arms 3
    Legs 2

    Player Skeleton Rig
    Head 2
    Torso 15
    Arms 3
    Legs 2

    I believe destiny does something similar to this. When your in the tower and you change a piece of armor, your character reloads with that armor. I am pretty sure they apply a shader and do not render the player character so as not to show anything ugly while the new armor loads. I suspect this due to a bug I encountered when a friend changed his chest piece and his torso disappeared while his limbs and head floated until the chest loaded, The same appears to occur for weapons as well. The player changes weapons and a shader is applied while the weapon loads.

    I am not worried about file size overall, just about performance at run time. My target is current gen consoles and PC. When considering consoles optimization is key. Thanks again for all the help!
     
  21. silentneedle

    silentneedle

    Joined:
    Mar 14, 2013
    Posts:
    280
    @masterprompt Could you please add a fbx instead of blender file at your git repo? Unfortunately I don't have blender installed, so unity is unable to convert it.
     
    Hydronet and JamesArndt like this.
  22. Ramsdal

    Ramsdal

    Joined:
    Oct 18, 2013
    Posts:
    251
    Whoops forgot to reply in this thread it seems!

    Well the result was what I needed, I ended up saving my models with the relevant bones and stitching them using almost exactly your code. With a little extra work I managed to get it working with full inventory and swappable equipment as I needed.

    Thanks @masterprompt and others who contributed here! :)

    @silentneedle I had to install it as well, it is a good tool to have https://www.blender.org/ ;)
     
  23. markashburner

    markashburner

    Joined:
    Aug 14, 2015
    Posts:
    212
    Is there a C# version of the original script?
     
  24. Ramsdal

    Ramsdal

    Joined:
    Oct 18, 2013
    Posts:
    251
    I am building on top of the script from @masterprompt and as you can see here it is c#.

     
  25. Beef-Tooth

    Beef-Tooth

    Joined:
    Nov 27, 2012
    Posts:
    23
    Like Nitoh above, I would love to get the Playmaker adaptation of this code.
    Fufurata1234 posted one a couple years ago but the link has died :(
     
  26. Lee7

    Lee7

    Joined:
    Feb 11, 2014
    Posts:
    137
    This script works great. Thank you and also thanks to masterprompt.

    For anyone who trys to use this but are not getting expected results; The meshes for all items needs to have a skin modifier. Usually things like cloth or armor chest pieces will always have one but sometimes things like helmet wont, they just can simply parent to a bone and be fine. BUT if you want to use this script for all of your armor pieces just add a skin modifier in your 3D program and set all vertices to the appropriate bone and it will work great.

    Again, thanks!
     
    theANMATOR2b likes this.
  27. wherewolfjohnson

    wherewolfjohnson

    Joined:
    Jan 20, 2016
    Posts:
    6
    I'm a complete newbie so I have some questions. I downloaded masterprompts stitch.cs file but how exactly do I use it? Say I have a character in Maya with a body and then a helmet weighted to the head bone. Do I delete the helmet and export that as avatar with bones, then reload, delete the body and export just the helmet with bones? Once I import both of these FBX files in unity do I attach the script to the avatar? How would I call the function, does he mean initiate playback?

    Any step by step guide for a complete newbie would be appreciated!
     
  28. MP84

    MP84

    Joined:
    Mar 7, 2015
    Posts:
    7
    Thanks for all these information and scripts. This is my final script (it has to be attached to the avatar):

    Code (CSharp):
    1. public class ItemsController : MonoBehaviour
    2. {
    3.     // gear, cloth etc. with SkinnedMeschRendered you want to add to this gameObject with bones
    4.     public GameObject newItem;
    5.  
    6.     // this is only for testing
    7.     public void OnGUI()
    8.     {
    9.         if (GUI.Button(new Rect(0, 0, 100, 30), "Add Item"))
    10.         {
    11.             AddNewItem(newItem);
    12.         }
    13.     }
    14.  
    15.     private void AddNewItem(GameObject item)
    16.     {
    17.         // find SkinnedMeschRendered on this gameObject
    18.         var existingItem = GetComponentInChildren<SkinnedMeshRenderer>();
    19.  
    20.         var newObj = Instantiate<GameObject>(item);
    21.         foreach(var r in newObj.GetComponentsInChildren<SkinnedMeshRenderer>())
    22.         {
    23.             // move the SkinnedMeshRenderer object from instantiated item to this object
    24.             // and change its rootBone and bones properties
    25.             r.transform.parent = transform;
    26.             r.transform.name = item.name;
    27.             r.rootBone = existingItem.rootBone;
    28.             r.bones = existingItem.bones;
    29.         }
    30.         Destroy(newObj);
    31.     }
    32. }
    That is all. It is that simple because
    1. there is no "bones migration". I just use bones from existing SkinnedMeshRender, because in all my tests these separated items (saved in extra files) contains the same bone structure as my character. Not sure if there are any scenarios where it will not work, but I am using Blender and these items are saved with the same armature (bones) as my avatar.
    2. I do not create child object with SkinnedMeshRenderer on my character every time I want to add new item. I just use SkinnedMeshRenderer from instantiated item. The item is destroyed at the end anyway and I do not need to copy its properties (bounds, materials,...).
     
  29. andysctu

    andysctu

    Joined:
    Jun 14, 2014
    Posts:
    20
    Hi @masterprompt I am just a little confused.

    I have a model of an arm in Blender. There is also a skeleton. However, it is not rigged yet (moving the skeleton does not move the model when in pose mode).

    Do I need to rig it before I import it to unity?

    In Blender, it looks like this



    Thanks!
     
  30. MP84

    MP84

    Joined:
    Mar 7, 2015
    Posts:
    7
    Yes, you need to rig it with the same skeleton as your main model.
     
  31. andysctu

    andysctu

    Joined:
    Jun 14, 2014
    Posts:
    20
    @MP84 Thanks for the response,

    I rigged my main model using Mixamo, if you're familiar with that.

    What would be the easiest way to re-rig all my parts?

    Create a new humanoid armature in Blender, then generate rig for each part?
     
    Last edited: Feb 15, 2016
  32. MP84

    MP84

    Joined:
    Mar 7, 2015
    Posts:
    7
    I am sorry, but I am not familiar with Mixamo's rigging. I do not know how output after the rigging looks like, but if the output is just FBX file (or something similar) with model and skeleton, you can still use above approach, I think.

    So you have one file with your main model and bones (rigged by Mixamo). Then you just create new file with the same bone structure (use the original file and delete the main model), where your new body parts/clothes/gear are attached to that bones (armature). In such case you should be able to use skinned meshes from the second file on our main model.
     
    theANMATOR2b likes this.
  33. andysctu

    andysctu

    Joined:
    Jun 14, 2014
    Posts:
    20
    Just to clarify, this means I need to skin the new body part to the old bones right? Using weight painting or whatever in Blender?
     
    Last edited: Feb 16, 2016
  34. andysctu

    andysctu

    Joined:
    Jun 14, 2014
    Posts:
    20
    @MP84 I just finished rigging (weight painting in blender) one part and it took a really long time ... I have a lot of parts to do, is there a faster way?
     
  35. Lesnikus

    Lesnikus

    Joined:
    Aug 29, 2015
    Posts:
    47
    I use this script for MakeHuman character and i get this horror freak: 1.jpg 2.jpg

    Any ideas?
    Here is a general view of the settings: 3.jpg
     
  36. MP84

    MP84

    Joined:
    Mar 7, 2015
    Posts:
    7
    You can use Blender's auto rigging. In object mode if you select your model, then add the armature to your selection and hit Ctrl+P. This should make armature parent of your model. The operation opens a context menu, where you can select "with automatic weights" or something like that. The auto rigging works quite well in most cases.
     
  37. MP84

    MP84

    Joined:
    Mar 7, 2015
    Posts:
    7
  38. andysctu

    andysctu

    Joined:
    Jun 14, 2014
    Posts:
    20
    @MP84 Yes I've been doing that too. Sometimes it fails because it can't complete some bones, but usually it requires some extra tweaking. The stitching script is working though.
     
    Last edited: Feb 17, 2016
  39. Dmtuan

    Dmtuan

    Joined:
    Feb 25, 2013
    Posts:
    4
    Hi,

    firstly, thank you for the informations on the stiching topic. It was very informative. I would like to know if the code provided by @masterprompt and @Ramsdal will work if some of my body parts have additional bones.

    See, for my models I have hair, head and body part. Some of the bodies have additional bones or some hair models (some longer hair with various shapes). My question is, will the stitching code provided here merge all the bones into one correct skelton?
     
  40. Dmtuan

    Dmtuan

    Joined:
    Feb 25, 2013
    Posts:
    4
    Also I have a question about Animating a character which has been assembled from the parts. If we take such character and try to animate it with Animator Controller, what Avatar do we use? If it was a model which was imported as a whole, we normally would take that as an Avatar. What do we do in the case of assembled character?
     
  41. WHReaper

    WHReaper

    Joined:
    Mar 10, 2016
    Posts:
    1
    Hi @MP84,
    I tried using your script and I have run into an issue. I tried using it with two models from Taichi character pack (free on asset store) and used one as "clothing". The script seems to copy the skinned mesh renderer correctly, but the model used as clothing will simply disappear. If I select the clothing Skinned Mesh Renderer (after it is copied by he script) in hierarchy, I can see it is just empty box in the scene. Do you have any idea what might be wrong?

    Also for anyone interested, there is also a bit hacky solution: Apply the same animator controller to the clothing as to your character. Then add new variable to your character's script you are using to control the animator. Then assign the clothing animator to this new variable via inspector. And each time you do some change to the animator component of your character, do the same change to the clothing animator. It should work, although it is not exactly elegant way to achieve this.
     
  42. jorger12

    jorger12

    Joined:
    Nov 19, 2015
    Posts:
    1
    Hello!
    Based on script of '@masterprompt', i have modified for multiple accesories, releasing unused memory resources.
    Credits: @masterprompt. Thanks !!! ;) DynamicAddCloth.jpg
     

    Attached Files:

  43. Lesnikus5

    Lesnikus5

    Joined:
    May 20, 2016
    Posts:
    131
    @masterprompt, I have a problem. The script works, but if i bring the camera (in the game-view or in a scene-view does not matter) to the body part that was attached to a character, body part becomes invisible. If i zoom out the camera, the body part becomes visible again. How to explain this?

    I tried script of jorger12 as well, but the problem remained.

    Here are the screenshots, where I brought the camera and head disappeared (only visible edged of model, because it is selected),
    Безымянный.jpg


    and the following screenshot shows how I alienated the camera and head again became visible.
    Безымянный2.jpg
     
  44. specterdragon

    specterdragon

    Joined:
    Dec 30, 2013
    Posts:
    21
    That could be hard to diagnose without more info.

    You may be able to diagnose this by having the character turn its head and see what happens to the attached part. If it turns in-place, then it might be (and this is just a guess) that the head bones have been offset from their parent but the head is skinned correctly. If the head swings widely as the main avatar's head turns, then it might indicate that the skinning is incorrect - that the bone is outside of the head when skinned.

    Another possibility might be the name of the bone(s) - is the child your attaching a perfect match for the parent?

    Again, these are just guesses.
     
  45. Vit3D

    Vit3D

    Joined:
    May 2, 2015
    Posts:
    64
    Hi Lesnikus5,

    I had similar issue when worked at my GR Modular Character System.
    In my case I managed to fix it by setting "Update When Offscreen" flag to "True" .
    Hope this will help.

    Cheers,
    Vit
     
  46. Lesnikus5

    Lesnikus5

    Joined:
    May 20, 2016
    Posts:
    131
    Yes, it works! Thank you. But this is not correct and reduces perfomance. Is it possible to fix it completely (without "Update When Offscreen" flag to "True")?
     
  47. Vit3D

    Vit3D

    Joined:
    May 2, 2015
    Posts:
    64
    Hi Lesnikus5,

    This issue happened because when You add new mesh part to the character the Bounds for this parts may become incorrect. To fix this issue You should change Update flag or re-calculate definition for Bounds.
    Yes, "Update When Offscreen" flag someway affect on performance, but, by my opinion, because "construct from parts" method usually used for main characters which practically always "on screen" performance reducing will be very small.
    If You will create script for Bounds re-calculation, will be very kind of You to share it in this post.

    Good luck,
    Vit
     
    JamesArndt likes this.
  48. Lesnikus5

    Lesnikus5

    Joined:
    May 20, 2016
    Posts:
    131
    Hi! A have a new problem.

    Nothing is satisfactory until I came to the import into the project of the clothing that belongs to the legs, ie trousers, pants and so on. They adding to the body of the character buggy. Right leg twisted 180 degrees on the vertical axis. Everything else works. Jackets, shirts, etc. also work without problems.

    Here pants, standing by themselves (not added to the body of the character):

    1.jpg

    But the pants in the game, has added to body using script (disabled visibility of the character body, to better see the pants). As you can see, right leg twisted:

    2.jpg


    Link to my project with demonstration this problem- https://yadi.sk/d/FhZ0SXNBsjjHM

    What's the matter?! I verifies the correctness of the names of all the bones, thought, where can the letter accidentally added a letter - in pants and torso completely identical skeletons! At the same time a female character that's all right, bug happening only with men's clothes (weird, huh?). Pick up the buggy Men's pants and drop (using script) this on a woman's body (skeletons of the all characters is identical) - the same problem! Pants twists on female and the male bodys equally. If I do not use a script, and add pants on scene, add them animator controller, they will normally run, jump, without bugs. It is necessary to apply script - again there is a bug (with any feet-clothing: pants, shorts, etc) ... What do you think?
     
    Last edited: Jun 23, 2016
  49. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    5,684
    UMA is a character slotting system very similar to this, and a common problem new UMA users have when making body parts is occasionally a mesh or bone doesn't have the default rotation or scale. It sounds like something with the male right leg pants got accidentally flipped in the modeling stage.
     
  50. masterprompt

    masterprompt

    Joined:
    Jan 6, 2009
    Posts:
    115
    It's been a long time since I've worked on this. Here are a few videos of it in action from that long ago: