Search Unity

  1. We would like to hear your feedback about Unity and our products. Click here for more information.
    Dismiss Notice

UMA - Unity Multipurpose Avatar on the Asset Store!

Discussion in 'Assets and Asset Store' started by FernandoRibeiro, Dec 24, 2013.

  1. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    4,592
    If you're using a DynamicCharacterAvatar, you should be using Wardrobe Items and Races - your base race recipe would have the slot(s) and overlay(s) that define the default race. New overlays for the skin would be assigned to wardrobe items so you can swap them out (for example, to the "body" or "face" slot - see the example face swap recipe. Using the wardrobe system makes this all much easier than dealing with recipes. If this isn't clear, let me know.
     
    Ne0mega likes this.
  2. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    4,592
    How are you saving the avatar? It looks like you are trying to mix UMA 1.X code and UMA 2.X code.
    If you want to do things the old way, you should use a DynamicAvatar. If you want to do things the new way, use a DynamicCharacterAvatar.

    Anyway, if you have a recipe *saved from a valid DynamicCharacterAvatar* and want to load it, use LoadFromAsset(umatextrecipe).

    SetSlot is for when you want to equip something - like a Hat or Coat.
     
  3. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    4,592
    I'll look at it. Likely it is scanning for something that isn't found. I put in a trello task so I don't forget. Until then you can of course, collapse the UMAData and/or DynamicCharacterAvatar in the inspector.
     
  4. pegassy

    pegassy

    Joined:
    Sep 28, 2017
    Posts:
    44
    Ok, so I did save the character's avatar in game using UMA/Load and Save/Save DynamicCharacterAvatar(s) txt (optimized). I saved it under Assets/Resources/CharacterRecipes, as this was suggested in some documentation.
    upload_2019-5-18_22-1-5.png

    It is working when I try to load character from scratch using the Load/Save Options/Load Path Type: Resources /Load Path: Character Recipes. The file is named "Fenvir", and that is the only thing I typed into the the Load Filename slot.
    upload_2019-5-18_22-2-59.png

    So I want to call such a txt file using an event, say when I am picking up a new costume. In order to do that I did call DynamicCharacterAvatar.LoadFromAssetFile(string). However, if I am entering only "Fenvir" this time it gives me a warning:

    Asset 'Fenvir' Not found in Global Index
    UnityEngine.Debug:LogWarning(Object)
    UMA.CharacterSystem.DynamicCharacterAvatar:LoadFromAssetFile(String) (at Assets/_MISC/UMA/Core/Extensions/DynamicCharacterSystem/Scripts/DynamicCharacterAvatar.cs:2392)
    UnityEngine.Events.UnityEvent`1:Invoke(GameObject)
    PixelCrushers.TriggerEvent:OnTriggerEnter(Collider) (at Assets/_TOOLS/Plugins/Pixel Crushers/Common/Scripts/UnityEvents/TriggerEvent.cs:36)

    I tried to use the long file path name, and Fenvir.txt but these did not work and I kept getting the warning. What is the right way to write that string in there?

    upload_2019-5-18_22-6-2.png

    I will be very happy if I can get this to work finally. Thank you for all your help.
     
  5. umutozkan

    umutozkan

    Joined:
    Oct 30, 2015
    Posts:
    305
    I am not sure how to make what you are doing work but I have another approach for different textures on same race.

    I have default skin textures and afro skin textures on my race. Both are on the same race base recipe as different overlays. Each one is on a different shared color. Afro shared color has alpha value of 0. When I increase the alpha value on that shared color it becomes visible. (It can also be bound to a DNA, that's how I use it.)

    If you want to check it out it's free on UAS. https://assetstore.unity.com/packages/3d/characters/humanoids/o3n-male-and-female-uma-races-102187
     
  6. pegassy

    pegassy

    Joined:
    Sep 28, 2017
    Posts:
    44
    I have purchased several cape and robe based assets for UMA, and for most of my current animations in my current project they seem to be poking through the elbows or feet. I tried using some cloth based solutions for regular humanoid meshes, but how do you do that with UMA given that the mesh is generated in runtime? I would also be interested in trying that for UMA based hair meshes.
     
  7. bobbyrocks

    bobbyrocks

    Joined:
    Jan 27, 2014
    Posts:
    11
    Real quick question and its probably and easy one. So I created a Torso chest piece asset... The chest piece is longer down the legs area but when i put it on my uma it only shows the chest area and not the model past the legs area.. Is there a way I can create a one piece armor set for chest and legs without using the legs asset and make it show right? I would assume its like a robe but cant seem to figure out how this is done. Probably something I am doing in my modeling software.
     
  8. dbrowndev87

    dbrowndev87

    Joined:
    May 19, 2019
    Posts:
    1
    I have the exported the Uma character model into Mixamo and the hands dont animate. any way to fix this issue??
     
  9. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    4,592
    You should just be able to use the existing mixamo animations with the unity export option without rerigging the UMA character. You will need to switch the TPose on the race to the "mecanim friendly" version.
     
  10. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    4,592

    Most likely you created it with two different materials. In this case, it will create two slots. You will need to add both slots to your recipe. That is by far the most common reason for this.
     
  11. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    4,592
    You can add one of the physics slots to your "additional utility recipes", and it will create colliders for you.
     
  12. Yerkisk

    Yerkisk

    Joined:
    Jul 28, 2015
    Posts:
    7
    Hi,

    We've recently switched our android project using UMA to il2cpp instead of Mono to prepare for the fact that Google Play will require 64bit architecture soon. Since then, our clients are sometimes crashing on DynamicUMADna ValidateValues called from the Set method of dnaAsset in the same class from what we could figure out using tools like addr2line to understand the crash dump. The error code we receive is :

    Code (CSharp):
    1.  
    2. IdleHandler threw exception
    3. java lang error signal 11 (sigsegv) code 1 (segv_maperr)
    4.  
    Unity and Google are of no help, as they keep closing the issue as no repro. From what I could read from some old threads here and there is that it might be related to threading.

    Does that sound familiar to anyone?

    Thanks
     
    Last edited: May 21, 2019
  13. LukeDawn

    LukeDawn

    Joined:
    Nov 10, 2016
    Posts:
    319
    Got a problem with the latest download on the Store. Lots of errors relating to "BlendShapeSettings" which doesn't exist in the package. (Clean install on a blank project in 2018.3.13f1)
     
    ThatKiwiGuy likes this.
  14. kenamis

    kenamis

    Joined:
    Feb 5, 2015
    Posts:
    328
    BlendShapeSettings has been a class in UMA for a while, since 2.6 I think. Did you maybe forget to update your asset cache? I'm not sure why you'd be getting errors for it missing. Can you post some of those error messages?
     
  15. Graham-B

    Graham-B

    Joined:
    Feb 27, 2013
    Posts:
    213
    Hi,

    I've been playing with the dynamic BoneyTail example and it's pretty great, but I'm running into an issue when removing or replacing the dynamic hair. Afterwards the extra bones from the ponytail are left behind, and they remain active on top of that. This could get quite heavy after swapping a handful of dynamic hairstyles in and out and being left with unused active physics objects.

    Is there a built in way to deal with this? I thought maybe I would find a slot event related to removing an item but didn't find anything. Would it be advised to manually rebuild the skeleton after swapping hairs?

    If you could point me in the right direction, I would be extremely grateful!
     
  16. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    4,592
    I recall someone had a similar issue with some DNA, which turned out to be null DNA. But it wasn't intermittent. The DNA stuff shouldn't be running on a worker thread, unless you've added multi-threading to your project.
     
  17. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    4,592
    We have a trello task to take care of this in 2.9 (we'll clear out "extra" bones during the build).

    But for now, you can just delete the root bone, and it should be rebuilt.
     
    hopeful likes this.
  18. Graham-B

    Graham-B

    Joined:
    Feb 27, 2013
    Posts:
    213
    Thanks for the quick reply. I am not sure I understand, because I am running into some issues while trying this.

    Are you referring to the root of the extra bones? Deleting this (PonyTail1) after unequipping it results in it never being equippable again, doing so leads to a completely pink and broken DCA.

    I am guessing you were referring to the character "root". Deleting this results in a console error as well as doubled UMARenderer children.

    MissingReferenceException: The object of type 'Transform' has been destroyed but you are still trying to access it.
    Your script should either check if it is null or you should not destroy the object.
    UMA.UMASkeleton.GetBoneGameObject (System.Int32 nameHash) (at Assets/UMA/Core/StandardAssets/UMA/Scripts/UMASkeleton.cs:327)
    UMA.Examples.MouseOrbitImproved.GetTarget (UnityEngine.Transform dstTarget) (at Assets/UMA/Examples/Legacy Examples/Scripts/MouseOrbitImproved.cs:132)
    UMA.Examples.MouseOrbitImproved.UpdatePos (UnityEngine.Transform dstTarget) (at Assets/UMA/Examples/Legacy Examples/Scripts/MouseOrbitImproved.cs:177)
    UMA.Examples.MouseOrbitImproved.LateUpdate () (at Assets/UMA/Examples/Legacy Examples/Scripts/MouseOrbitImproved.cs:171)

    If I delete both UMARenderer and Root every time I equip a new hairstyle, I still get the console error, but it seems to work, however there is a flicker while the character is being generated over a frame or so while its not visible.

    Am I missing something? Thanks again for your time!
     
  19. Bartek_Gudowski_Friend_Factory

    Bartek_Gudowski_Friend_Factory

    Joined:
    Feb 18, 2019
    Posts:
    25
    Hi!

    Does anybody know if its possible to have a normal map connected to a slider for body DNA etc. For example if you change muscle mass, that it also adds on a normal map with defined muscles.

    And is it possible to work Set Driven Keys for blendshapes in Unity (as in Maya)?

    Many thanks!
     
  20. LukeDawn

    LukeDawn

    Joined:
    Nov 10, 2016
    Posts:
    319
    Ah, my bad it was Will B's asset pack overwriting the core. Unchecking everything but the content folder sorted it.
     
  21. AmandaAlavi

    AmandaAlavi

    Joined:
    Sep 14, 2018
    Posts:
    2
    Hello, I'm wondering if it's possible to create presets similar to what they have in Character generators in apps (like memoji, zepeto). Where you can pick a shape for the eyes, jaw, etc. I want the sliders too for extreme changes. But I want to be able to create presets which the users can pick from. I know you can make bone pose presets, but I don't want it as a slider, and I want it to work with blendshapes as well. I want it to be more similar to the wardrobe function, with icons, etc, that overwrites earlier choices, so you cant layer eye shapes upon eye shapes. But I don't want it to be a mesh exchange, just changing bones and blendshapes as I said before.

    Thank you so much!
     
  22. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    4,592
    Yes - You would have two different overlays (with two different normal maps). Take a look at the "DynamicDNAConverterControllerDemo" scene. there is a DNA called "ElfOrAlien" on the character.

    This DNA works by modifying the alpha value of the normal map on an overlay.
    The race has two overlays - one with a muscular normal map, and one with a smooth normal map.
    The smooth one is on top, so the normal for it is manipulated in the DNA.
     
  23. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    4,592
    You can create "characters" that contain various DNA modifications, and then switch between them.
    You can create "races" that contain various DNA modifications, bone poses, overlays, etc, and then switch between them.
    But for the specific thing you are looking for you would need to manage manually. I do plan to add the "predefined DNA" to the wardrobe recipes next version, and that would do what you wanted (you'd have a wardrobe slot for each specific preset). But that will probably be a few weeks out before it is ready, and then you'd need to use a pre-release version of UMA until the release.
     
  24. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    4,592
    Yeah, you have to delete the child objects right before building the character, or in the "RecipeUpdated" event. I missed the renderer, you have to delete it also.

    But I do have this on the list of things to fix in next release, maybe a couple months out.

     
    Graham-B likes this.
  25. Ne0mega

    Ne0mega

    Joined:
    Feb 18, 2018
    Posts:
    115
    Is there any kind of batching in uma? I read that each uma gets its own material. Does this include cloned prefabs? Is there any way uma could know that an uma has the exact same colors, slots, layouts etc. basically, is there any point to using say a "skin palette" limited to 5 colors, or would a spectrum be just as efficient?
     
  26. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    4,592
    There is currently no batching in Default UMA. It is on our roadmap to detect and reuse texture atlases, but even that won't really help (beyond lower the amount of texture ram used). The problem is really that you can't batch skinned mesh renderers in most cases, because they are animated and the actual rendered mesh has to be calculated.

    Note: there are some attempts to do this by pre-rendering a skinned mesh animations into a texture here:

    https://blogs.unity3d.com/2018/04/16/animation-instancing-instancing-for-skinnedmeshrenderer/

    But you're not really getting instanced meshes, it's more like imposters.

    If you're seeing some performance problems, be sure you are using the LOD system. You can lower the amount of texture RAM needed dramatically - and automaticallly, it really is a big improvement. You can also switch in lower poly slots, decreasing draw time further. Take a look at the randomizer scene, I believe it generates 200 UMA's at one time and the framerate is still very good on my intel graphics.

    Of course, if you need to have 20,000 characters on the screen, then you'll have to go to great lengths to get that working -- generating imposters for far away characters, dramatically lowering the bone count, texture sizes, etc.

    If you are using prefabs created with the power tools, then you are getting the same material on cloned prefabs. Note that these are not customizable prefabs though (ie - you can't change the hair, or repurpose it by loading a new character on it), but you will save a lot of texture space, and of course skinning time is improved because of decreased bone count.
     
    Ne0mega likes this.
  27. m4a44

    m4a44

    Joined:
    Mar 13, 2013
    Posts:
    17
    Hey, looking to add an extra bone to the UMA humanoid. Been looking around and can't find any proper tutorial or much of anything else (or it's just buried in this thread and I couldn't find it).

    Basically, I'm looking to add a weapon slot bone (in the right hand) to the UMA so it can be animated through the Unity animator. Need the weapon to move separate from the hand.

    It works in Unity, but I haven't found a way to move it into UMA...
     
  28. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    4,592
    The new UMA character save has the shared colors in it like this:

    "characterColors":[{"name":"Skin","colors":[238,234,225,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0]},{"name":"Hair","colors":[90,55,36,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0]},{"name":"Eyes","colors":[73,104,255,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0]},{"name":"Undies","colors":[255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0]},{"name":"Pants","colors":[255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0]},{"name":"PantsAccent","colors":[255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0]},{"name":"Shoes","colors":[255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0]},{"name":"Shoes Accent","colors":[255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0]}]

    There are two RGBA pairs for each color channel (first one is multiplied, and second one is added). And one color channel for each texture.

    In this case, there are three channels.

    The first shared color is named "Skin". The diffuse texture channel is multipled by RGBA 238,234,225,255. Muliplication "colorizes" things, and is normally what you think of when you set a color on a texture. the second color in the channel is 0,0,0,0 - since the second color is additive, this basically does nothing. The normal map and metallic map for the first colors are both "255,255,255,255" (multiplied) and "0,0,0,0" (added). Since 255,255,255,255 is actually "1,1,1,1" in float values, that results in nothing happening also.


     
  29. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    4,592
    Any bones that are added to a slot have to have a vertex weighted to that bone somewhere, or they are discarded during the build. You can add a vertex somewhere where it won't be noticed (hidden by the hand or whatever you will be attaching) to make this work (you may need to make it a tiny triangle... don't recall right off). After UMA thinks it's needed, it will include the bone and you can access it after the build.

    Or you can run the Bone Builder and add the bone manually in Unity. But if you repurpose the character, that could be lost on rebuild in some cases.

    We have a trello task to make this better (mark bones as required, and discard unneeded bones after being added), but it will be a while before it is completed.

     
  30. m4a44

    m4a44

    Joined:
    Mar 13, 2013
    Posts:
    17
    Ok, got something working. The whole "bone needs to be weightpainted" for a slot threw me off. Thanks.
     
  31. EnriquePage91

    EnriquePage91

    Joined:
    Jul 2, 2015
    Posts:
    50
    Dear fellow UMA friends (and dev team),

    I am working on a custom race integrating Daz3D characters into UMA. As you might know, DAZ3D offers a TON of blendshapes. Particularly, there are many blendshapes such as "Cheek crease" which have a version for both Left and Right side, while simultaneously separating it into Cheek Crease - L, and Cheek Crease - R (the naming is different but this should be clear enough).

    This scenario repeats itself quite a lot when utilizing DAZ characters, I have around 25 blendshapes that have been separated into Left and Right sides, while also including a "global" (both Left and Right) blendshape.

    I imagine (although I'm not sure), that every blendshape on my character will have to be stored on the memory while the character is in use, however since I've learned how to program on my own a lot of the knowledge necessary here, is missing to me.

    If I have around 190 blendshapes on my custom race, would I see a substantial benefit in performance if I decide to remove the "global" blendshapes and simply utilize the "Left" and "Right" variants together when needed (to replicate the Global blendshape by utilizing the variants)? Or am I taking this too far?

    This is particularly important for the face, and naturally I will be isolating the Face mesh into it's own slot to avoid having such blendshapes be included for the body, arms, legs, etc. Still, even when we're only talking about perhaps 1000 vertices, I'm not sure how good of an idea it will be to keep BOTH the variants, and the GLOBAL blendshapes.

    I know this might sound like a very small issue, but my main concern is:

    If I keep the global blendshapes, it might be easier and more organized to utilize these to "modify" the shape of the character (such as the Cheek creases), while at the same time being able to utilize the variants for animation (adding the "Left" or "Right" variants to other expressions such as frowning, smiling, etc).


    In essence, how can I calculate or estimate the performance difference that I should expect when comparing the following characters with 15k verts: one including 150 blendshapes to the other one containing around 200?

    Thank you so much, you guys are always very helpful and I really appreciate you taking the time to help out.

    All the best,

    Enrique
     
  32. Vortavasail

    Vortavasail

    Joined:
    Apr 22, 2016
    Posts:
    44
    thanks but is there a special way to save the name of the colors are not labeled just a Dash.

    only looking for "Skin" "eyes" "hair"
    "characterColors":[{"name":"-","colors":[152,243,213,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0]},
     
  33. DankP3

    DankP3

    Joined:
    Jul 17, 2017
    Posts:
    62
    @EnriquePage91 , I'll let Jaimi or similar respond on memory use, there was such a discussion a few pages back. You could recreate your global blendshape by creating a DNA value that operates both blendshapes?
    For what its worth, it sounds like a lot of blendshapes and i expect a performance hit (and possibly some extra 'interactive licenses'!), but you seem prepared for that. Just be careful of some of the peripheral facial blendshapes as they will also need to be on the torso (as their effect reaches into the torso) or you risk slot separation.
     
    EnriquePage91 likes this.
  34. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    4,592
    The "-" means that the color was not a shared color. Actually, I'm not sure how you are even seeing those, as they're not normally saved with the character.

    How are you saving the character?

    It should produce something that looks like this:


    {"packedRecipeType":"DynamicCharacterAvatar","name":"UMADynamicCharacterAvatar_DCSRecipe","race":"HumanMale","dna":[{"dnaType":"DynamicUMADna","dnaTypeHash":815443803,"packedDna":"{\"bDnaAsset\":{\"instanceID\":22800},\"bDnaAssetName\":\"HumanMaleDynamicDnaAsset\",\"bDnaSettings\":[{\"name\":\"skinGreenness\",\"value\":128},{\"name\":\"skinBlueness\",\"value\":128},{\"name\":\"skinRedness\",\"value\":128},{\"name\":\"height\",\"value\":128},{\"name\":\"headSize\",\"value\":128},{\"name\":\"headWidth\",\"value\":128},{\"name\":\"neckThickness\",\"value\":128},{\"name\":\"armLength\",\"value\":128},{\"name\":\"forearmLength\",\"value\":128},{\"name\":\"armWidth\",\"value\":128},{\"name\":\"forearmWidth\",\"value\":128},{\"name\":\"handsSize\",\"value\":128},{\"name\":\"feetSize\",\"value\":128},{\"name\":\"legSeparation\",\"value\":128},{\"name\":\"upperMuscle\",\"value\":128},{\"name\":\"lowerMuscle\",\"value\":128},{\"name\":\"upperWeight\",\"value\":128},{\"name\":\"lowerWeight\",\"value\":128},{\"name\":\"legsSize\",\"value\":128},{\"name\":\"belly\",\"value\":128},{\"name\":\"waist\",\"value\":128},{\"name\":\"gluteusSize\",\"value\":128},{\"name\":\"earsSize\",\"value\":128},{\"name\":\"earsPosition\",\"value\":128},{\"name\":\"earsRotation\",\"value\":128},{\"name\":\"noseSize\",\"value\":128},{\"name\":\"noseCurve\",\"value\":128},{\"name\":\"noseWidth\",\"value\":128},{\"name\":\"noseInclination\",\"value\":128},{\"name\":\"nosePosition\",\"value\":128},{\"name\":\"nosePronounced\",\"value\":128},{\"name\":\"noseFlatten\",\"value\":128},{\"name\":\"chinSize\",\"value\":128},{\"name\":\"chinPronounced\",\"value\":128},{\"name\":\"chinPosition\",\"value\":128},{\"name\":\"mandibleSize\",\"value\":128},{\"name\":\"jawsSize\",\"value\":128},{\"name\":\"jawsPosition\",\"value\":128},{\"name\":\"cheekSize\",\"value\":128},{\"name\":\"cheekPosition\",\"value\":128},{\"name\":\"lowCheekPronounced\",\"value\":128},{\"name\":\"lowCheekPosition\",\"value\":128},{\"name\":\"foreheadSize\",\"value\":128},{\"name\":\"foreheadPosition\",\"value\":128},{\"name\":\"lipsSize\",\"value\":128},{\"name\":\"mouthSize\",\"value\":128},{\"name\":\"eyeRotation\",\"value\":128},{\"name\":\"eyeSize\",\"value\":128},{\"name\":\"breastSize\",\"value\":128},{\"name\":\"eyeSpacing\",\"value\":128}]}"}],"characterColors":[{"name":"Skin","colors":[238,234,225,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0]},{"name":"Hair","colors":[90,55,36,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0]},{"name":"Eyes","colors":[73,104,255,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0]},{"name":"Undies","colors":[255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0]},{"name":"Pants","colors":[255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0]},{"name":"PantsAccent","colors":[255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0]},{"name":"Shoes","colors":[255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0]},{"name":"Shoes Accent","colors":[255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0]}],"wardrobeSet":[{"slot":"Underwear","recipe":"MaleUnderwear"},{"slot":"Chest","recipe":"MaleShirt01_Torso"},{"slot":"Legs","recipe":"M_Wanderer_Legs"},{"slot":"Feet","recipe":"M_InnKeeper_Feet"},{"slot":"Hair","recipe":"MaleHairSlick01_Recipe"}],"raceAnimatorController":"Locomotion"}
     
  35. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    4,592

    Every single Blendshape will increase the size of your files by the number of vertexes in the mesh. So if your mesh has 15k verts, then each blendshape will increase your memory usage by 15k verts worth of blendshapes - regardless of whether a vertex is moved or not. Having as few blendshapes as possible should be the goal. Like DankP3 says, you can always combine them in DNA so they appear to be a single blendshape.
     
  36. EnriquePage91

    EnriquePage91

    Joined:
    Jul 2, 2015
    Posts:
    50
    Thanks for the help!

    Let me start with a quick opinion on Daz3D:

    Yes, I am accounting for the licenses: I am actually only using 4 licenses, and if you stay on top of your game, it's actually kinda crazy how little you can pay for licenses in DAZ by buying at the right time, and paying for the Daz subscription (which you can do for 3 months right before purchasing, adding around 20 dollars to your bill).

    I ended up spending around 130 dollars but got quite a lot of content by buying 4 bundles (and the licenses at another time, when they were discounted by 50%). It certainly isn't super cheap, but there's just no equivalent on the asset store as far as I have seen for character meshes, especially considering that the standard Genesis characters' interactive licenses are already included for free on Daz3d (or at least that was the case for me, not sure if it's because I bought something first), meaning that I get to extract all the juicy shapes from Daz3d and not do them myself.

    This has in fact saved me a lot of time, far more than what I could account for with the 130-ish dollars I spent on such content and its licenses, so I would definitely recommend it, particularly since from the around 200 shapes I brought up into a single character, only 30 or so are based on paid licenses, the rest are simply from the Genesis system (which seems to have a free interactive license). I have then done some additional work by creating additional shapes, or modifying some of these. I have isolated many of these to conform to the different slots so that ultimately things can be optimized (I believe this is the case right?). With some cool Blender tricks, you can quickly isolate them on the least amount of possible slots (so, the face thing your bring up has been accounted for, only blendshapes that really need to be "global" affect all slots), since Blender allows you to define vertex group masks for such blendshapes and then bake the result into a new one very quickly.

    But Anyway...

    What would the number of acceptable blendshapes be for a mesh of 15k then? I saw a talk about Spider-Man's latest game which I still haven't played so I can't comment on performance but they did bring up that they STREAM the blendshapes (?... not sure how, I guess meshes are generated dynamically; similar to UMA). Also that they had over 400 blendshapes on the npcs. Perhaps UMA will offer such possibilities eventually? In my particular case, I have certain shapes which are global and modify the entire mesh to look slightly different (think of the licensed characters). What I can certainly see as a first use, would be to only stream the necessary "licensed blendshapes" for the mesh in use, in such way that I don't have "15 additional licensed characters" on an UMA which is only utilizing one. Another use would naturally be adding visemes only when needed, and stuff like that.

    But moving on from my fantasies...:

    Given that my character has 15k, but certain blendshapes are isolated to specific slots (such as expressions only existing in the Face Slot mesh and what not), then it should be expected that for example, for a particular face slot blendshape there will only be an additional X number of vertices accounted for in memory, where X corresponds to the number of vertices the face slot contains, right?

    Naturally, many of the blendshapes I brought up, are isolated to the face (around 60-70%), so this should at least help out a lot, but only if things are as I believe. Some have also been isolated to the legs, or arms, etc. So I have done this work because my impression was I could benefit from it in performance.



    As a comment about the DNA suggestion:

    I am aware I could do it through DNA, however I'd like my animation system to not have to consider the fact that certain blendshapes have been utilized to "modify the look of the character" beforehand. What I'm trying to say, is:

    Let's say I have a "cheek crease" shape for both L and R sides, such cheek creases could be used to form the character's shape, but ultimately also be utilized when animating to accentuate expressions. In such case, I'd rather not have to account for the initial "added" value on such shape which is only meant to modify how the character looks globally.

    I am not sure if I'm making myself clear, but ultimately the point is: I find an organization use to having both a global "cheek crease" shape that I can utilize to modify the character's shape, and then 2 separate L/R variants used for animation. This is merely for the purpose of being able to simply interpolate from 0 to 100 per shape when animating, as otherwise I'd have to account for the initial value through code. Or would accounting for this really be the most acceptable way of doing things? I have no issue with doing it, but it just seems like if I can get away from not taking this into account, things will be simpler. Although I know there will be a slight performance hit, what I'd like to know is how sever that would be.

    I know this might be asking far too much since it is quite outside of what UMA is, but in general, how many verts should one expect to be able to hold in memory on a mid-end mobile device? On a mid-end PC? I'm not sure of the cost in kb per vertex, but I'm sure it's not simply a Vector3 kinda thing as UVs have to be stored to. And then again, since unfortunately I did not study programming at an academic level, I wouldn't necessarily understand such level of intricacy.

    Ultimately, If I have a single race, and spawn 10 characters out of it, does this mean that the memory will have to allocate space for the 200-ish blendshapes of EACH of these characters even if they are the same shapes? or is there a sort of UMA buffer storing such data beforehand to only keep track of one "instance" per blendshape?

    Thank you both so much for the support, I really appreciate any advice you can give me, and what you have contributed already!
     
    Last edited: May 23, 2019
  37. kenamis

    kenamis

    Joined:
    Feb 5, 2015
    Posts:
    328
    It will depend highly on your use case and target platforms.

    One blendshape is an array of vector3's (actually up to 3 arrays) the same size as the mesh vertex count you are adding the blendshape too. One for delta vertex, one for delta normal, and one for delta tangent. So if you want a deformation for your cheek, it will still require the size of your entire mesh it will be added to.

    Part of the point of UMA is to dynamically combine the parts of the character and materials so that the final character is one (or as few as possible) draw calls. Because of this the mesh and render texture per UMA is a unique instance.

    There are two metrics involved with blendshapes. The cost per UMA generation and cost per frame. The cost per frame is small, but not negligible. If you can use the new GPU version (I think 2018.3+ on supported platforms), I think it's faster. The cost per UMA generation is the costly part and will go up depending on the size of the target mesh (no matter how many vertices are actually affected) and the number of blendshapes being added.

    Unity blendshapes allow for smooth runtime morphing of the mesh, but sometimes that's not actually needed. Like for example, setting "muscularity" during character creation. After that value is set, then usually you don't need the character dynamically changing. In that case UMA has a feature of "blendshape baking". That can "bake" the offset of a particular blendshape value during UMA generation. That is much faster for UMA generation and no extra per frame cost. To be clear, you can mix various blendshapes of some full Unity blendshapes and others as baked.

    Finally, you could split up part of the UMA into separate renderers at the cost of additional draw calls, but could greatly speed up your UMA generation that is using lots of blendshapes. For example, if you split off the head into it's own renderer and add many blendshapes to that that aren't included on the body. You can do that currently in UMA by assigning the head slots to a new UMA Material that is tagged with "Separate Renderer". There is a new feature coming that will allow more UMA Renderer Management too.
     
    hopeful and EnriquePage91 like this.
  38. EnriquePage91

    EnriquePage91

    Joined:
    Jul 2, 2015
    Posts:
    50

    Amazing post! Thank you so much I will research the necessary aspects. This is incredible thank you!
     
    kenamis likes this.
  39. Vortavasail

    Vortavasail

    Joined:
    Apr 22, 2016
    Posts:
    44
    I'm just trying to get test data. so I just run the game and use the UMA menu at the top with a Uma selected, then save normal and optimized both give just a "-" for the name of the color.
     
  40. pegassy

    pegassy

    Joined:
    Sep 28, 2017
    Posts:
    44
    I could really use some help to understand how this works. Thank you.
     
  41. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    4,592
  42. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    4,592
    To get the shared colors and text file like I posted, you need to be using a DynamicCharacterAvatar, and use the "Save DynamicCharacterAvatar(s) txt (optimized)" menu option. That will save the colors as they are defined on the character - you can see those in the "CharacterColors" section of the DynamicCharacterAvatar.

    Please post the contents of the txt file obtained from the procedure above, and I'll look at it.
     
  43. Tarball

    Tarball

    Joined:
    Oct 16, 2016
    Posts:
    142
    Hi, I need to save UMA DNA from a Dynamic Character Avatar as JSON in postgreSQL on my Linux server. To save the DNA text, I've tried the following three commands

    Code (CSharp):
    1. SendToPG(JsonUtility.ToJson(avatar.GetCurrentRecipe()));
    2.  
    3. SendToPG(avatar.GetCurrentRecipe());
    4.  
    5. SendToPG(avatar.GetCurrentRecipe().ToString());
    and postgreSQL always complains the same thing: NpgsqlException: ERROR: 22P02: invalid input syntax for type json. What am I doing wrong? I thought UMA outputs json string with

    Code (CSharp):
    1. avatar.GetCurrentRecipe();
    What format does that spit out? If it's json, postgreSQL does not like it. How can I reformat the recipe without changing the UMA code itself? Thanks.
     
  44. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    4,592
    It's json - created with the unity json formatter. To test, I pasted it into the json formatter/validator here:

    https://jsonformatter.curiousconcept.com/

    and received this back:
    json.jpg
    I do not know how your postgresql function works, but if you have not paramterized the insert, then the quotes and backslashes could be causing havoc with your SQL.


     
    Tarball and hopeful like this.
  45. Tarball

    Tarball

    Joined:
    Oct 16, 2016
    Posts:
    142
    Thanks, but I didn't mean that I thought it was corrupted or something. I just haven't ever done this before, and I'm a little puzzled why it doesn't work. Essentially, this is my postgreSQL INSERT after all the network stuff:
    Code (CSharp):
    1. cmd.CommandText = "INSERT INTO character_data (account_name, character_name, dna_and_equipment) VALUES (@n, @p, @q)";
    2. cmd.Parameters.Add(new NpgsqlParameter("@n", acct_name));
    3. cmd.Parameters.Add(new NpgsqlParameter("@p", char_name));
    4. string dna = avatar.GetCurrentRecipe();
    5. cmd.Parameters.Add(new NpgsqlParameter("@q", dna));
    I have little experience with json, but I picked postgreSQL as a database because it takes json data directly. Have any of you used the Npgsql driver before, by chance? They claim "Out of the box, Npgsql allows reading and writing these types [json and jsonb] as strings and provides no further processing" on
    https://www.npgsql.org/doc/types/jsonnet.html
    Also, I've been following this guide for postgreSQL:
    http://www.postgresqltutorial.com/postgresql-json/
     
  46. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    4,592
    what type of field is "dna_and_equipment"?
     
  47. Tarball

    Tarball

    Joined:
    Oct 16, 2016
    Posts:
    142
    It's json not null.
     
  48. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    4,592
    I can't find anything wrong. The json is valid, but postgresql is saying it's not. perhaps something specific to your UMAs are causing an error? You might try pasting your json into that formatter above, and see if it has some problem.
     
  49. Tarball

    Tarball

    Joined:
    Oct 16, 2016
    Posts:
    142
    Good idea. I did that, and it says it's valid. But, then I noticed that some quotes are escaped and others aren't in the generated string. Here is an example:

    Code (CSharp):
    1. {"packedRecipeType":"DynamicCharacterAvatar","name":"Character","race":"HumanFemale","dna":[{"dnaType":"DynamicUMADna","dnaTypeHash":1932961400,"packedDna":"{\"bDnaAsset\":{\"instanceID\":108582},\"bDnaAssetName\":\"HumanFemaleDNA 1\",\"bDnaSettings\":[{\"name\":\"height\",\"value\":84},{\"name\":\"headSize\",\"value\":128},{\"name\":\"headWidth\",\"value\":128},{\"name\":\"neckThickness\",\"value\":128},{\"name\":\"armLength\",\"value\":128},{\"name\":\"forearmLength\",\"value\":128},{\"name\":\"armWidth\",\"value\":128},{\"name\":\"forearmWidth\",\"value\":128},{\"name\":\"handsSize\",\"value\":128},{\"name\":\"feetSize\",\"value\":128},{\"name\":\"legSeparation\",\"value\":128},{\"name\":\"upperMuscle\",\"value\":63},{\"name\":\"lowerMuscle\",\"value\":128},{\"name\":\"upperWeight\",\"value\":128},{\"name\":\"lowerWeight\",\"value\":128},{\"name\":\"legsSize\",\"value\":128},{\"name\":\"belly\",\"value\":128},{\"name\":\"waist\",\"value\":76},{\"name\":\"gluteusSize\",\"value\":128},{\"name\":\"earsSize\",\"value\":128},{\"name\":\"earsPosition\",\"value\":128},{\"name\":\"earsRotation\",\"value\":128},{\"name\":\"noseSize\",\"value\":128},{\"name\":\"noseCurve\",\"value\":128},{\"name\":\"noseWidth\",\"value\":128},{\"name\":\"noseInclination\",\"value\":128},{\"name\":\"nosePosition\",\"value\":128},{\"name\":\"nosePronounced\",\"value\":128},{\"name\":\"noseFlatten\",\"value\":128},{\"name\":\"chinSize\",\"value\":128},{\"name\":\"chinPronounced\",\"value\":128},{\"name\":\"chinPosition\",\"value\":128},{\"name\":\"mandibleSize\",\"value\":128},{\"name\":\"jawsSize\",\"value\":128},{\"name\":\"jawsPosition\",\"value\":128},{\"name\":\"cheekSize\",\"value\":128},{\"name\":\"cheekPosition\",\"value\":128},{\"name\":\"lowCheekPronounced\",\"value\":128},{\"name\":\"lowCheekPosition\",\"value\":128},{\"name\":\"foreheadSize\",\"value\":128},{\"name\":\"foreheadPosition\",\"value\":128},{\"name\":\"lipsSize\",\"value\":128},{\"name\":\"mouthSize\",\"value\":128},{\"name\":\"eyeRotation\",\"value\":128},{\"name\":\"eyeSize\",\"value\":128},{\"name\":\"breastSize\",\"value\":207},{\"name\":\"breastCleavage\",\"value\":128},{\"name\":\"eyeSpacing\",\"value\":128},{\"name\":\"green\",\"value\":128},{\"name\":\"red\",\"value\":128},{\"name\":\"blue\",\"value\":128}]}"}],"characterColors":[{"name":"Skin","colors":[247,221,192,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0]},{"name":"Hair","colors":[155,77,62,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0]},{"name":"Eyes","colors":[255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0]},{"name":"Undies","colors":[255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0]}],"wardrobeSet":[{"slot":"Face","recipe":"FFace2"},{"slot":"Eyes","recipe":"MaleEye5"},{"slot":"Underwear","recipe":"FemaleUndies2"},{"slot":"Hair","recipe":"FHair8"},{"slot":"Eyebrows","recipe":"FEyebrow2"},{"slot":"Eyelashes","recipe":"Fem_Eyelash"}],"raceAnimatorController":"char_control"}
    The ones on the inside are all escaped, but the outer ones are not. is that normal? I noticed that because I was trying to make a small dotnet script to test with so i didn't have to upload the whole server for small changes/testing. I can't hard code the json if all the quotes aren't escaped though.

    If I manually escape them all, I get the following error:
    Code (CSharp):
    1. column "dna_and_equipment" is of type json but expression is of type text
    Now, I suppose this makes sense, because I haven't included ::json casting at the end of the INSERT command. But, honestly, I'm not sure how I would do that since I'm not casting "@n" and "@p". They all have to be replaced at the same time, or the not null on "@r" won't be satisfied. Plus, it needs the account name and character name identifiers to ensure it's in the correct row.

    I appreciate the help, especially since this is an open source project.
     
  50. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    4,592
    Maybe someone else, or someone from the npgsql or postgresql mailing lists or forums might be able to help, at this point I don't really know what is going on.