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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

UMA Character System (deprecated)

Discussion in 'Assets and Asset Store' started by Jaimi, Dec 1, 2015.

  1. Hedonsoft

    Hedonsoft

    Joined:
    Jul 11, 2012
    Posts:
    168
    Thanks Jaimi! :)
     
  2. evil_genie

    evil_genie

    Joined:
    Sep 10, 2015
    Posts:
    8

    Thanks for the help! I think I get it... I'm guessing I can follow this method for creating a recipe:

    http://uma.unity3d.com/wiki/index.php/UMA_Recipe_tutorial

    And if not I'll give your other method a try. I'll try it out and let you know if I run into any trouble.
     
  3. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    6,171
    I'll need to update the wiki with the updated procedures, but it's kind of different now.

    1. Right click in a folder in the project window, and select Create/UMA Text Recipe, and rename it to whatever you want.
    2. After selecting the recipe in the project window, you can now edit it in the inspector.
    3. You should see a warning that there is no race data set - click the button next to the race data, and select a valid race for the recipe.
    4. Select the slot tab
    5. Drag/Drop any slot (or slots), or folder containing slots onto the area that says "Drag slots here".
    6. For each slot, you'll need to add one or more overlays, by dropping OverlayDataAssets onto the field labelled "Add Overlay".
    7. If you are using Shared Colors to recolor your assets, you need to add shared colors in the Shared Color editor. There needs to be the same number of colors in each shared color, as there are textures in your overlay -- typically an overlay will have 3 textures, so normally a shared color has 3 colors. Give the Shared Colors names so you can access them in code. Typical colors include "Hair", "Eyes", "Skin", but you can name them what you want, or have as many as you want.
    8. After adding Shared Colors press the "Save Collection" button.
    9. Check the box on the Overlay that needs to have a Shared Color, and select the correct color.
    10. If you are using the CharacterSystem - then set the sex/wardrobe/hides/suppress fields, and press "Save Asset".
     
  4. Teila

    Teila

    Joined:
    Jan 13, 2013
    Posts:
    6,929
    Hey Jaimi,

    I decided to try some of Arteria's new UMA medieval dresses. I set up the recipe and it all looks good. However, try as I might, I cannot hide or suppress the legs. I have tried multiple combinations, checked and rechecked to make sure I have the slot name correct, but the legs still show with the dress.

    Any suggestions? It doesn't work the way the maiden did for some reason. Take that back, the maiden isn't hiding the torso either anymore. Weird..because it did before.
     
    Vinchinderlous likes this.
  5. Teila

    Teila

    Joined:
    Jan 13, 2013
    Posts:
    6,929
    Okay, figured out part of the problem. I had space comma. No space. :)
     
    Vinchinderlous and hopeful like this.
  6. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    6,171
    Yeah, sorry about that. I need to make that whole process better. My plan is to put in an array editor, so you can add,delete items. Maybe I can add a utility into the new UMA Utility panel that I wrote (all it does now is mass set some of the fields on selected recipes).

    Also - like Steve's new dresses. His UMA work is improving.
     
    Last edited: Jan 13, 2016
  7. Teila

    Teila

    Joined:
    Jan 13, 2013
    Posts:
    6,929
    Actually, Jaimi, while the above helped with the maiden dress, it did not help with the Arteria dresses. Nothing seems to make the legs go away. Weird. I will play with it a bit more tomorrow.
     
    Vinchinderlous likes this.
  8. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    6,171
    Are you using Will's modular bodies/overlays? I'll try to duplicate the issue.
     
  9. Teila

    Teila

    Joined:
    Jan 13, 2013
    Posts:
    6,929
    Oh, I should have posted last night..but was so tired! lol

    It had to have something to do with the scene. I was using UMA's recipe mixer scene. Once I switched to your scene, the one included with the package it works great. :) Now just trying to find good animations. So far, Mixamo works very well as long as you upload the rig and go through the autorig. Otherwise there are a lot of nasty glitches.

    Dresses look good but only if you hide the legs. Feet only is okay, but still some bleed through, which I guess is expected as the dresses are very very long. No feet works but looks weird when running and no feet poke out. :)
     
    Vinchinderlous and hopeful like this.
  10. Hedonsoft

    Hedonsoft

    Joined:
    Jul 11, 2012
    Posts:
    168
    I've always had problems with Mixamo animations on UMA. I uploaded the Male or Female basemesh and apply the animations.. They look fine in the previewer but when I import them into Unity they are extremely wonky. What is your process?
     
  11. Teila

    Teila

    Joined:
    Jan 13, 2013
    Posts:
    6,929
    Upload the Unified or separated human with the rig to Mixamo's autorigger. It will then automatically go to the animation window. Choose your animations and make sure the UMA character is in the window. We also found that using the Dude character, auto-rigging him and attaching the animations works too. Make sure that one of them is attached to the animation when you download it.

    We have had issues with some of the animations in any 3rd person controller we try to use..maybe it has to do with the blending of the animations. We are trying to work through those issues.
     
    Vinchinderlous and hopeful like this.
  12. Teila

    Teila

    Joined:
    Jan 13, 2013
    Posts:
    6,929
    Oh, and don't forget to change the rigs to Humanoid after you import them into Unity. Very important! Also, change the UMA character you use for the upload to Mixamo to Humanoid before you upload.
     
    Vinchinderlous and hopeful like this.
  13. Hedonsoft

    Hedonsoft

    Joined:
    Jul 11, 2012
    Posts:
    168
    Thanks!
     
  14. buronix

    buronix

    Joined:
    Dec 11, 2013
    Posts:
    111
    Hi all,

    I have some problems importing an slot overlay into UMA, I have the same issue as reported in https://github.com/huika/UMA/issues/50,

    But it was reported on September/8 with not answers at all, so Im trying to get some help here.

    Its an exception in runtime when the avatar is creating:

    And I debug the exception point with this result (SkinnedMeshCombiner.cs:149):
    Code (CSharp):
    1. if (has_uv2)
    2. {
    3.    if (source.meshData.uv2 != null)
    4.    {
    5.      Debug.Log("Source: Length: " + source.meshData.uv2.Length + " Destination Length: " + uv2.Length +
    6.      " VertexIndex: " + vertexIndex + " vertexCount: " + vertexCount +" UV: "+ source.meshData.uv.Length);
    7.      Array.Copy(source.meshData.uv2, 0, uv2, vertexIndex, vertexCount);
    8.    }
    The Debug Shows:
    Source: Length: 0 Destination Length: 18760 VertexIndex: 0 vertexCount: 508 UV: 508

    Im using last UMA 2 version from Asset Store and Last Unity 5.3.

    When I Saw the UmaData of the Avatar in the Inspector I Saw this :



    The Problematic Overlay/Slot is Sword01.

    I tryed to not load the overlay and the Error dissapear, but ofc the sword is not shown.

    I tryed with different Materials, Uma Diffuse Normal Metallic, UMA Fade Diffuse, Uma Legacy, Always changing the Material both overlay and slot, and with the right diffuse, normal and specular textures, but the error is always the same as the result of the Slot in the UmaData Inspector.

    Thanks in Advance.
     

    Attached Files:

    Last edited: Jan 21, 2016
  15. Teila

    Teila

    Joined:
    Jan 13, 2013
    Posts:
    6,929
    Curious...I never thought of putting in a weapon as a slot like that. Isn't there a better way to do it?
     
    Vinchinderlous likes this.
  16. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    5,628
    Probably having the weapon in a character slot is a good idea if you want the character to have a specific weapon with a customized appearance. It becomes part of the recipe.

    If you want characters to be able to pick up and use items, you wouldn't want to have those as slots.

    But there are no restrictions I can think of for one way or the other.
     
    Teila likes this.
  17. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    6,171
    Hmm - I didn't see anything wrong in the code right off - to fix this, I'd need the mesh/overlay/SlotDataAsset/OverlayDataAsset. If you can email them to me, I can take a look at it, see if I can code a fix (PM me for my email). It's likely something strange, like perhaps the second UV count isn't the same as the vertex count or something like that. Just curious - what do you use the second set of UV's for?

     
  18. buronix

    buronix

    Joined:
    Dec 11, 2013
    Posts:
    111
    Right Now Im using the weapons as child of the "XHand" (Right-Left) Transform in my Character, but I though it was a good idea to add them as slot/overlay for my NPCs.

    Hi I pm you for the email,

    About the second UV, Im not using it at all, its only the error cause, If I can remove it or something like that maybe the error would be gone, I dont know, Im quite new with UMA/Unity, Im a software developer, trying to learn Unity to develop a Game, so I am learning a lot of stuff but my knowledge is not enough to understand this problem.
     
  19. Teila

    Teila

    Joined:
    Jan 13, 2013
    Posts:
    6,929
    UMA is difficult so don't feel bad. Just have to slog through it all and it will come to you in a flash of lightning..and then it all makes sense. :)
     
    Vinchinderlous likes this.
  20. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    6,171
    I think if the count of materials is very important, then using them as a slot/overlay is a good idea. Otherwise, I think adding them as a child of the hand bone is preferable.

    Anyway - fixed the issue with multiple UV and checked it in. You can get the latest version from GIT with the fix in it.
     
  21. MikeyUchiha

    MikeyUchiha

    Joined:
    Jan 8, 2011
    Posts:
    109
    Jaimi, will this work with DK UMA 2?
     
  22. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    6,171
    Not sure - it seems like they may do similar things (manage wardrobe, manage overlays, etc). I've got helper utilities for designing your own character editors (sample coming in the update).
    But in the end, you end up with a standard avatar, and if anything can work with that, then it should work.
     
  23. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    6,171
    Just a quick update - I have a new version almost ready to go. Has the bug fixes that I've found and fixed, plus the latest updated UMA from github. I've spent a lot of time making a generic editor system as well, to edit the DNA as well as the wardrobe slots and colors on the avatar. I'll try to get it uploaded by the weekend.
     
    Teila, BackwoodsGaming and hopeful like this.
  24. buronix

    buronix

    Joined:
    Dec 11, 2013
    Posts:
    111
    Hi Jaimi,

    Right now Im working on a UMA project and Im thinking to use your Character System for it, Im pretty new with UMA but I have a basic knowledge of it, but I have wide range of programming skills and experience, What do you think about put this on github (or bitbucket or whatever system you prefer) and collaborate to improve it?.

    Kind Regards.

    Ruben.
     
  25. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    6,171
    As everyone can see, I missed my weekend upload with the update. I did however find some time to add some improvements. I'm almost ready to upload a new version that allows you to edit all the normal things - DNA, The various wardrobe parts, and the shared colors. This includes all the UI helper classes to do things in a generic fashion, so you can craft it into any sort of UI you like.

    I'm actually quite keen on this - I talked with Unlogick a few weeks ago, and he's OK with me adding it to UMA itself in the extension folder.
     
    Moerk75, hopeful and Teila like this.
  26. Moerk75

    Moerk75

    Joined:
    Apr 16, 2013
    Posts:
    22

    I get some weird results using the dna? or is it intentional?.

    Anyhow when I try out the color and use the dark color it just looks like the light is turned of. Looks a bit weird.

    Maybe I am just doing something wrong.
     
  27. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    5,628
    We can't see your pictures.
     
  28. Moerk75

    Moerk75

    Joined:
    Apr 16, 2013
    Posts:
    22
    Weird.PNG Color.PNG
    Here they are.
     
  29. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    6,171
  30. Moerk75

    Moerk75

    Joined:
    Apr 16, 2013
    Posts:
    22
    Well extremes are great but the results look more than weird. Going opposite I get some weird deformation results. I have not seen these results before so just wanted to know.

    The rest of what you are working on looks great.
     
  31. davidosullivan

    davidosullivan

    Joined:
    Jun 9, 2015
    Posts:
    387
    Hey Jaimi, today I realized I was 're-inventing the wheel' by making something very similar to your UMA Character System so I am having a more in depth look at it...

    One thing I was wondering, is that back in September you asked on the UMA forum:-
    and Ecurtz replied here

    Now I know a bit more about what is going on, I have just realized what Ecurtz says there may prove a MAJOR spanner in the works for me, and I was wondering how you got around the Slot/Asset library restriction thing?

    What I mean is, I DO absolutely need my users to be downloading UMA Slots and overlays as Asset bundles, and I'll be using something like your character system to enable users to customise their characters with those slots, so I may not know what slots in what scenes the user is actually using...

    Is the solution here something like making a DynamicSlotLibrary and a DynamicOverlayLibrary that just fills itself up on request with all the slots and overlays it can find do you think? I am guessing that also one would have to put all your Slots and Overlays in the Resources folder to begin with (Rather than the UMA folder) do you think?

    From what I can see your system still relies on prebuilt Slot/Overlay libraries, but I was just wondering if you ever tried out making your system have UMA Avatars load the slots they require as they need them?

    Very interested to hear your thoughts on this since I can see you already had a look into it?
     
    hopeful likes this.
  32. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    5,628
    @davidosullivan - As you probably know (but others new to it may not), UMA was designed back in the dark days before Unity 5, when most users were suffering under various onerous indie restrictions, like being limited to forward / gamma, no render textures, no asset bundles, etc.

    To make the original UMA, Fernando and Joen had to jump through a lot of flaming hoops that are now unnecessary. While some great U5 features like PBR have been incorporated already, I bet UMA2 can also make significant improvements to asset management.
     
  33. davidosullivan

    davidosullivan

    Joined:
    Jun 9, 2015
    Posts:
    387
    Actually, looking at this it appears that probably I should be thinking about putting Slots and Overlays into AssetBundles rather than Resources... No idea how that might work... I had a pretty fundamental misunderstanding about AssetBundles. Because I keep reading that the Resources folder, internally, is an AssetBundle, somehow I had gotten it into my head that once an AssetBundle had been downloaded you could just do 'Resources.LoadAll<UMARecipeBase> () and get all the Recipes that exist in the game, the ones in the Resources folder and the ones in any downloaded AssetBundles, but I dont think you can. Apparently you have to specifically say which assetBundle you want to load from, and since in the case we are discussing here, you would not know what asset bundles had been downloaded, or what bundles could be or could have ever been downloaded, I am struggling to see how a dynamic list could even be generated... :(
     
    hopeful likes this.
  34. davidosullivan

    davidosullivan

    Joined:
    Jun 9, 2015
    Posts:
    387
    @Jaimi is there anyway that a wardrobe slot could also get rid of an overlay on another slot.
    For example in this picture the model could perhaps do with her bra removed, in my chracters and models its even more necessary sometimes as they wear halternecks and backless dresses...
    OverlayRemoval.jpg
     
  35. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    5,628
    @davidosullivan - From that thread you referenced, superpig says:

    Note that as well as using WWW, you can also use AssetBundle.CreateFromFile.

    This only works with uncompressed AssetBundles, but that's likely what you want anyway - they take up more disk space, but far less memory (only the 'index' of the bundle is loaded into memory when you create it, the actual resources are only loaded when you request them - as opposed to compressed AssetBundles which have to be fully loaded into memory). The Resources folder generates an uncompressed bundle as well so you shouldn't find that it uses any more disk space than before.

    Combine it with putting your asset bundles into the StreamingAssets folder, so that the bundles are automatically packed into your builds, and you've got yourself something that is very similar to the Resources folder but supports incremental building, more fine-grained control over loading and unloading, etc...​
     
  36. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    6,171
    Yes - that's built into the system. This is what you would do:

    1. Edit the base recipe for the character, so that it did not have the bra.
    2. Create a new WardrobeSlot in the enum for the bra. It would have to go before the shirt slot.
    3. Create a bra recipe, and add it to your character.
    3. On your shirt recipes, tell it to supress the bra Wardrobeslot.
     
  37. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    6,171
    This all works out, because the system merges recipes and discards duplicate UMA Slots, so the effect is that the Body UMA slot is added with the skin, then the bra is added, and then the shirt added. (it goes in order of the enum). If the Bra Wardrobeslot is suppressed, it never gets added to the queue.
     
  38. davidosullivan

    davidosullivan

    Joined:
    Jun 9, 2015
    Posts:
    387
    Ok great I can work with that. In the thing I was making I was saving the generated recipes in the same way that UMA does if you ask it to save the recipe as a text file (i.e. as a json string). With both litJson in UMA and json Utilities in Unity 5.3 this seems to work out ok.

    So I was just wondering why it was that you chose to make your files export as XML? XML files are miles bigger and I know they compress well when they are included in the build, but when you load them from Resources or an asset bundle I think I am right in saying that they get added verbatim, so they dont get compressed and are un-necessarily large.

    Interested to hear your thoughts on that...
     
  39. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    6,171
    Simply out of habit - XML is what I've used before, and it's easy to edit. The actual character XML files are pretty small, it's really only tracking the DNA, Recipes used, and the colors assigned. To create a JSON version shouldn't be too hard, I'll try to get to it.
     
  40. davidosullivan

    davidosullivan

    Joined:
    Jun 9, 2015
    Posts:
    387
    Ok fingers crossed :) XML is always massive because it wraps every part of an array in <myarraything>value</myarraything> for evey single value which all adds up...

    I'll probably send you some code when I get to this point because I already did this in my version....

    Right now I have to solve the assetBundle issue as a top priority and I'd like as much help on that as possible. Lots of people agree with me that UMA needs it, so I'd like to make something that is not bespoke but which becomes part of UMA if at all possible...
     
  41. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    6,171
    Sure - I'm working to get the full project into the base UMA, hopefully it will make things easier for people who are just looking for a turn-key system.
     
  42. davidosullivan

    davidosullivan

    Joined:
    Jun 9, 2015
    Posts:
    387
    Hi Jaimi, I have been working on modifying your CharacterSystem so that it can optionally use AssetBundles.
    One of the things I think I need to do is change CharacterSystem into a MonoBehaviour, that way the creator can set which asset bundle names to use, which resources folders and so forth, so that it does not have to load resources it doesn't need if its set up that way. I have made a version of this and it works fine. But I was wondering what your reasoning was for making Character System static in the first place?
     
  43. davidosullivan

    davidosullivan

    Joined:
    Jun 9, 2015
    Posts:
    387
    I tried using the singleton pattern in CharacterSystem and making it a MonoBehaviour- this enables me and others to make derivative classes from CharacterSystem but I think it should preserve the staticness you are after. All you need to do to make it work is overwrite the existing files and make a new GameObject in your demo scene and give that the CharacterSystem script and check the box for 'MakeSingleton'. Would this work out with your aims for CharacterSystem?
     

    Attached Files:

  44. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    6,171
    Making it a monobehavior has some performance side effects -- you have to search for it to use it in code. As a static class, it's available at load time and it's resolved at compile time.

    What I think would work would be to have a monobehaviour "CharacterSystemLoader" class that would access the static class, then we would have the best of both worlds -- you could serialize it, use asset bundles, and the static class would exist for internal use.
     
  45. davidosullivan

    davidosullivan

    Joined:
    Jun 9, 2015
    Posts:
    387
    Ok I am sure thats true. But did you check out my singleton version? That optionally instantiates itself as a static object, and then if thats the way you are using it you can reference it by doing CharacterSystem.Instance. But the developer can still change the way CharacterSystem works if they need to (like they can change alot of UMA since lots of things are declared as virtual classes). If CharacterSystem is static then basically everyone is stuck with it.
    Plus on the UMA forum I got a reply saying that the slotLibrary is a problem precisely because its kind of static in that, because it has to reference all the slots and overlays you might use those are always there even if they are not used. This would surely be a big issue if you had loads of optionally downloadable character packs...
    I have made versions now of Slot/Overlay/RaceLibrary that are interchangeable with the UMA ones, but if all your stuff is in the Resources folder (and possibly AssetBundles but I havent tested this yet) everything just gets loaded as its needed. So if you put all your races, slots and overlays into the Resources folder and set the Context to use my dynamic versions and dont set up any slots/overlays/races, those libraries just get populated on demand and everything still works...
    Files attached if you are interested...

    (P.S. if you do try those out you will need to look at the DynamicSlot/Overlay/RaceLibrary game objects and click the 'Dynamically Add from Resources' check box to see it actually doing that...)
     

    Attached Files:

  46. davidosullivan

    davidosullivan

    Joined:
    Jun 9, 2015
    Posts:
    387
    And also with the solution you suggest option the developer still has no control over what is loaded. In your version CharacterSystem still just loads ALL UMATextRecipes but what if you dont want that in one scene or another, you have no control- even forgetting assetbundles and stuff, you cannot even define the folder!

    I seriously think that is MASSIVELY restrictive, to the degree that developers are just going to copy the code into their own classes and not use yours because yours are just too prescriptive.
     
  47. davidosullivan

    davidosullivan

    Joined:
    Jun 9, 2015
    Posts:
    387
    For example in your code you hard code this:-
    Code (CSharp):
    1. TextAsset[] xmlfiles = Resources.LoadAll<TextAsset>("Characters");
    But if you just change it a bit I and any other user could customize that, surely that's worth doing? With my version I can do this:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System;
    5. using System.IO;
    6.  
    7. namespace UMACharacterSystem
    8. {
    9.     public class DynamicCharacterSystem : CharacterSystem {
    10.  
    11.         //extra fields for Dynamic Version
    12.         public bool dynamicallyAddFromResources;
    13.         public string resourcesCharactersFolder = "Characters";
    14.         public string resourcesRecipesFolder = "Recipes";
    15.         public bool dynamicallyAddFromAssetBundles;
    16.         public string assetBundlesForCharactersToSearch;
    17.         public string assetBundlesForRecipesToSearch;
    18.         [HideInInspector]
    19.         public bool refresh = false;
    20.  
    21.         void OnEnable(){
    22.             if (!initialized || refresh) {
    23.                 if (refresh) {
    24.  
    25.                 } else {
    26.                     Init ();
    27.                 }
    28.             }
    29.         }
    30.  
    31.         // Use this for initialization
    32.         void Start () {
    33.      
    34.         }
    35.      
    36.         // Update is called once per frame
    37.         void Update () {
    38.             if (refresh) {
    39.                 Refresh ();
    40.             }
    41.         }
    42.  
    43.         public override void Init(){
    44.             Debug.Log ("DynamicCharacterSystem Init");
    45.             if (initialized) {
    46.                 return;
    47.             }
    48.             // Create a dictionary for each sex.
    49.             foreach (UMACharacterSystem.Sex sx in Enum.GetValues(typeof(UMACharacterSystem.Sex))) {
    50.                 Recipes.Add (sx, new Dictionary<WardrobeSlot, List<UMATextRecipe>> ());
    51.             }
    52.             GatherXMLFiles ();
    53.             GatherRecipeFiles ();
    54.             initialized = true;
    55.         }
    56.  
    57.         public void Refresh(){
    58.             refresh = false;
    59.             Recipes = new Dictionary<Sex, Dictionary<WardrobeSlot, List<UMATextRecipe>>> ();
    60.             RecipeIndex = new Dictionary<string, UMATextRecipe> ();
    61.             XMLFiles = new Dictionary<string, string>();
    62.             initialized = false;
    63.             Init ();
    64.         }
    65.  
    66.         private void GatherXMLFiles(string filename = ""){
    67.             if (dynamicallyAddFromResources) {
    68.                 GatherXMLFilesFromResources (filename);
    69.             }
    70.             if (dynamicallyAddFromAssetBundles) {
    71.                 GatherXMLFilesFromAssetBundles(filename);
    72.             }
    73.         }
    74.         private void GatherXMLFilesFromResources(string filename = ""){
    75.             TextAsset[] xmlfiles = Resources.LoadAll<TextAsset>(resourcesCharactersFolder);
    76.             for (int i = 0; i < xmlfiles.Length; i++) {
    77.                 if (filename != "") {
    78.                     if (xmlfiles [i].name == filename.Trim() || xmlfiles [i].name.ToLower() == filename.Trim()) {
    79.                         XMLFiles.Add (xmlfiles [i].name.ToLower(), xmlfiles [i].text);
    80.                     }
    81.                 } else {
    82.                     XMLFiles.Add (xmlfiles [i].name.ToLower(), xmlfiles [i].text);
    83.                 }
    84.             }
    85.             StartCoroutine (CleanFilesFromResourcesAndBundles ());
    86.         }
    87.         private void GatherXMLFilesFromAssetBundles(string filename = ""){
    88.             string[] assetBundles;
    89.             if (assetBundlesForCharactersToSearch != "") {
    90.                 assetBundlesForCharactersToSearch.Replace (" ,", ",").Replace (", ", ",");
    91.                 if (assetBundlesForCharactersToSearch.IndexOf (",") == -1) {
    92.                     assetBundles = new string[1]{ assetBundlesForCharactersToSearch };
    93.                 } else {
    94.                     assetBundles = assetBundlesForCharactersToSearch.Split  (new string[1]{","}, StringSplitOptions.RemoveEmptyEntries);
    95.                 }
    96.             } else {
    97.                 AssetBundleManifest thisAssetBundleManifest = new AssetBundleManifest ();
    98.                 assetBundles = thisAssetBundleManifest.GetAllAssetBundles ();
    99.             }
    100.             for (int i = 0; i < assetBundles.Length; i++) {
    101.                 var assetBundleToSearch = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, assetBundles[i]));//From the docs BUT do asset bundles always get downloaded to the streaming asset path?
    102.                 if (assetBundleToSearch != null) {
    103.                     TextAsset[] xmlfiles =  assetBundleToSearch.LoadAllAssets<TextAsset> ();
    104.                     for (int ii = 0; ii < xmlfiles.Length; ii++) {
    105.                         if (filename != "") {
    106.                             if (xmlfiles [i].name == filename.Trim() || xmlfiles [i].name.ToLower() == filename.Trim()) {
    107.                                 XMLFiles.Add (xmlfiles [i].name.ToLower(), xmlfiles [i].text);
    108.                             }
    109.                         } else {
    110.                             XMLFiles.Add (xmlfiles [i].name.ToLower(), xmlfiles [i].text);
    111.                         }
    112.                     }
    113.                 }
    114.             }
    115.             StartCoroutine (CleanFilesFromResourcesAndBundles ());
    116.         }
    117.         private void GatherRecipeFiles(string filename = ""){
    118.             if (dynamicallyAddFromResources) {
    119.                 GatherRecipeFilesFromResources (filename);
    120.             }
    121.             if (dynamicallyAddFromAssetBundles) {
    122.                 GatherRecipeFilesFromAssetBundles(filename);
    123.             }
    124.         }
    125.         private void GatherRecipeFilesFromResources(string filename = ""){
    126.             UMATextRecipe[] uparts = Resources.LoadAll<UMATextRecipe>(resourcesRecipesFolder);
    127.             AddRecipes (uparts, filename);
    128.             StartCoroutine (CleanFilesFromResourcesAndBundles ());
    129.         }
    130.         private void GatherRecipeFilesFromAssetBundles(string filename = ""){
    131.             string[] assetBundles;
    132.             if (assetBundlesForRecipesToSearch != "") {
    133.                 assetBundlesForRecipesToSearch.Replace (" ,", ",").Replace (", ", ",");
    134.                 if (assetBundlesForRecipesToSearch.IndexOf (",") == -1) {
    135.                     assetBundles = new string[1]{ assetBundlesForRecipesToSearch };
    136.                 } else {
    137.                     assetBundles = assetBundlesForRecipesToSearch.Split (new string[1]{","}, StringSplitOptions.RemoveEmptyEntries);
    138.                 }
    139.             } else {
    140.                 AssetBundleManifest thisAssetBundleManifest = new AssetBundleManifest ();
    141.                 assetBundles = thisAssetBundleManifest.GetAllAssetBundles ();
    142.             }
    143.             for (int i = 0; i < assetBundles.Length; i++) {
    144.                 var assetBundleToSearch = AssetBundle.LoadFromFile (Path.Combine (Application.streamingAssetsPath, assetBundles [i]));//From the docs BUT do asset bundles always get downloaded to the streaming asset path?
    145.                 if (assetBundleToSearch != null) {
    146.                     UMATextRecipe[] uparts =  assetBundleToSearch.LoadAllAssets<UMATextRecipe> ();
    147.                     AddRecipes (uparts, filename);
    148.                 }
    149.             }
    150.             StartCoroutine (CleanFilesFromResourcesAndBundles ());
    151.  
    152.         }
    153.  
    154.         IEnumerator CleanFilesFromResourcesAndBundles(){
    155.             yield return null;
    156.             Resources.UnloadUnusedAssets ();
    157.         }
    158.  
    159.         public void AddRecipes(UMATextRecipe[] uparts, string filename = ""){
    160.             foreach (UMATextRecipe u in uparts) {
    161.                 if (filename == "" || (filename != "" && filename.Trim() == u.name)) {
    162.                     Dictionary<UMACharacterSystem.WardrobeSlot, List<UMATextRecipe>> SexRecipes = Recipes [u.Sex];
    163.  
    164.                     if (!SexRecipes.ContainsKey (u.Slot)) {
    165.                         SexRecipes.Add (u.Slot, new List<UMATextRecipe> ());  
    166.                     }
    167.                     SexRecipes [u.Slot].Add (u);
    168.  
    169.                     RecipeIndex.Add (u.name, u);
    170.                 }
    171.             }
    172.         }
    173.     }
    174. }
    175.  
    But this kind of customization is impossible with CharacterSystem as it stands. I totally understand if it turns out that my singleton version has major performance impacts it maybe a no go, but if not I really think there should not be any downside to it?
     
  48. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    6,171
    Hi David - it does load all the recipes, but only if you put them in a "Recipes" folder - you don't have to do that, it just makes it easier. You can still load them all manually, it really is just a cache -- a convenient place to hold the dictionaries. I did look at your code, and I agree it's nice, but I think we can come up with something that fits both of our requirements. One thing I was wanting to avoid was to have yet another UMA game object hanging around in the scene -- already there seems so much overhead with the generator, slot library, overlay library, race library, and mesh combiner.

    Still, I'm not convinced my way is the only way, or the best way. My first goal is to get my updated CharacterSystem with the working sample scene (with so much more than the sample in the upload above) into the main tree. Then, I promise I will take the code above and figure out the best way to work it in to fit all our needs.

    In the end, I would like to have a single "UMA Data" type object that hold everything, that is smart about what is loaded in memory, and makes everything easy to access -- and people wouldn't even need to create it, it would be created and loaded as needed - much like your Dynamic libraries.
     
  49. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    6,171
    I agree - it looks great and very helpful. But since the declarations of the dictionaries in the old class are public, Your DynamicCharacterSystem class doesn't need to derive from CharacterSystem - it can coexist with the static class, and simply load the static dictionaries in it. It doesn't need to derive from it. But still, again, I'm not convinced my way is the best way, just the way I would do it.
     
  50. davidosullivan

    davidosullivan

    Joined:
    Jun 9, 2015
    Posts:
    387
    Yeah my point though is that if we were to make this truly dynamic (i.e. that it could work with asset bundles and such) then 'I' wouldn't be able to control the size of this static list with your code as it stands. With my code I would be able to manipulate CharacterSystem so it only loaded content from certain folders/bundles...

    Regards not wanting to have 'yet another UMA game object hanging around' I think it should be possible to make this a replacement for the UMAContext itself and just use my dynamic libraries instead...

    And regards what you are doing I am 100% for collaborating. I need to come up with a solution ASAP and if it can be one that is part of UMA going forwards then that is better for me than if it is a bespoke hack. So right now, you and all the UMA developers have my 100% attention and time on this, so please use it and invite me into the 'inner circle'...