//Override Load from PackedRecipeBase
        /// <summary>
        /// Load this Recipe's recipeString into the specified UMAData.UMARecipe. If there is Wardrobe data in the recipe string, its values are set to this recipe assets 'activeWardrobeSet' field
        /// </summary>
        /// <param name="umaRecipe">UMA recipe.</param>
        /// <param name="context">Context.</param>
        public override void Load(UMA.UMAData.UMARecipe umaRecipe, UMAContextBase context = null)
        {
            //This check can be removed in future- If we set the recipeType properly from now on we should not need to do this check
            var typeInRecipe = GetRecipesType(recipeString);

            recipeType = typeInRecipe != "Standard" ? typeInRecipe : recipeType;
            if (RecipeHasWardrobeSet(recipeString))
            {
                activeWardrobeSet = GetRecipesWardrobeSet(recipeString);
            }
            //if its an old UMARecipe there wont be an activeWardrobeSet field
            if (activeWardrobeSet == null)
            {
                recipeType = "Standard";
                base.Load(umaRecipe, context);
                return;
            }
            //if it has a wardrobeSet or was saved using the DCSPackRecipe Model
            if (activeWardrobeSet.Count > 0 || (recipeType == "DynamicCharacterAvatar" /*|| recipeType == "WardrobeCollection"*/))
            {
                var packedRecipe = PackedLoadDCSInternal(context /*, recipeString*/);
                UnpackRecipe(umaRecipe, packedRecipe, context);
            }
            else             //we can use standard UMALoading
            {
                base.Load(umaRecipe, context);
            }
        }
        /// <summary>
        /// Save data from the specified UMA recipe.
        /// </summary>
        /// <param name="umaRecipe">UMA recipe.</param>
        /// <param name="context">Context.</param>
        public override void Save(UMA.UMAData.UMARecipe umaRecipe, UMAContextBase context)
        {
            umaRecipe.MergeMatchingOverlays();
            var packedRecipe = PackRecipeV3(umaRecipe);

            PackedSave(packedRecipe, context);
        }
 //This is used when an inspected recipe asset is saved
 public override void Save(UMAData.UMARecipe umaRecipe, UMAContextBase context)
 {
     if (recipeType == "Wardrobe")            //Wardrobe Recipes can save the standard UMA way- they dont have WardrobeSets- although the recipe string wont have a packedRecipeType field
     {
         base.Save(umaRecipe, context);
     }
     else if (recipeType != "Standard")            //this will just be for type DynamicCharacterAvatar- and WardrobeCollection if we add that
     {
         var packedRecipe = PackRecipeV3(umaRecipe);
         //DCSPackRecipe doesn't do any more work, it just gets the values from PackRecipeV3 that we need and discards the rest
         var packedRecipeToSave = new DCSPackRecipe(packedRecipe, this.name, recipeType, activeWardrobeSet);
         recipeString = JsonUtility.ToJson(packedRecipeToSave);
     }
     else             //This will be Standard- this is 'backwards Compatible' and is also how the Recipe Editor saves 'backwardsCompatible' 'Standard' recipes when they are inspected
     {
         umaRecipe.MergeMatchingOverlays();
         var packedRecipe       = PackRecipeV3(umaRecipe);
         var packedRecipeToSave = new DCSUniversalPackRecipe(packedRecipe);                //this gets us a recipe with all the standard stuff plus our extra fields
         //so now we can save the wardrobeSet into it if it existed
         if (activeWardrobeSet != null)
         {
             if (activeWardrobeSet.Count > 0)
             {
                 packedRecipeToSave.wardrobeSet = activeWardrobeSet;
             }
         }
         recipeString = JsonUtility.ToJson(packedRecipeToSave);
     }
 }
Пример #4
0
 /// <summary>
 /// Deserialize recipeString data into packed recipe.
 /// </summary>
 /// <returns>The packed recipe.</returns>
 /// <param name="context">Context.</param>
 public override UMAPackedRecipeBase.UMAPackRecipe PackedLoad(UMAContextBase context = null)
 {
     if ((recipeString == null) || (recipeString.Length == 0))
     {
         return(new UMAPackRecipe());
     }
     return(JsonUtility.FromJson <UMAPackRecipe>(recipeString));
 }
Пример #5
0
        public void Initialize()
        {
            if (context == null)
            {
                context = UMAContextBase.Instance;
            }

            if (umaData == null)
            {
                umaData = GetComponent <UMAData>();
                if (umaData == null)
                {
                    umaData           = gameObject.AddComponent <UMAData>();
                    umaData.umaRecipe = new UMAData.UMARecipe();                     // TEST JRRM
                    if (umaGenerator != null && !umaGenerator.gameObject.activeInHierarchy)
                    {
                        if (Debug.isDebugBuild)
                        {
                            Debug.LogError("Invalid UMA Generator on Avatar.", gameObject);
                            Debug.LogError("UMA generators must be active scene objects!", umaGenerator.gameObject);
                        }
                        umaGenerator = null;
                    }
                }
            }
            if (umaGenerator != null)
            {
                umaData.umaGenerator = umaGenerator;
            }
            if (CharacterCreated != null)
            {
                umaData.CharacterCreated = CharacterCreated;
            }
            if (CharacterBegun != null)
            {
                umaData.CharacterBegun = CharacterBegun;
            }
            if (CharacterDestroyed != null)
            {
                umaData.CharacterDestroyed = CharacterDestroyed;
            }
            if (CharacterUpdated != null)
            {
                umaData.CharacterUpdated = CharacterUpdated;
            }
            if (CharacterDnaUpdated != null)
            {
                umaData.CharacterDnaUpdated = CharacterDnaUpdated;
            }
            if (AnimatorStateSaved != null)
            {
                umaData.AnimatorStateSaved = AnimatorStateSaved;
            }
            if (AnimatorStateRestored != null)
            {
                umaData.AnimatorStateRestored = AnimatorStateRestored;
            }
        }
Пример #6
0
        static void CreateDynamicAvatarMenuItem()
        {
            var res = new GameObject("New Dynamic Avatar");
            var da  = res.AddComponent <UMADynamicAvatar>();

            da.context      = UMAContextBase.FindInstance();
            da.umaGenerator = Component.FindObjectOfType <UMAGeneratorBase>();
            UnityEditor.Selection.activeGameObject = res;
        }
 //TODO: once everyone has their recipes updated remove this- we only want UMATextRecipes to save as 'Standard'
 /// <summary>
 /// Saves a 'Standard' UMATextRecipe. If saving a DynamicCharacterAvatar as 'Backwards Compatible' this will save a recipe that has slots/overlay data AND a wardrobe set
 /// </summary>
 public void Save(UMAData.UMARecipe umaRecipe, UMAContextBase context, Dictionary <string, UMATextRecipe> wardrobeRecipes, bool backwardsCompatible = true)
 {
     if (wardrobeRecipes.Count > 0)
     {
         activeWardrobeSet = GenerateWardrobeSet(wardrobeRecipes);
     }
     recipeType = backwardsCompatible ? "Standard" : "DynamicCharacterAvatar";
     Save(umaRecipe, context);
 }
Пример #8
0
#pragma warning restore 618
        /// <summary>
        /// Finds the singleton context in the scene.
        /// </summary>
        /// <returns>The UMA context.</returns>
        public static UMAContextBase FindInstance()
        {
            if (Instance == null)
            {
                var contextGO = GameObject.Find("UMAContext");
                if (contextGO != null)
                {
                    Instance = contextGO.GetComponent <UMAContextBase>();
                }
            }
            if (Instance == null)
            {
                Instance = Component.FindObjectOfType <UMAContextBase>();
            }
            return(Instance);
        }
        /// <summary>
        /// Return a cached version of the UMA recipe, Load if required.
        /// </summary>
        /// <returns>The cached recipe.</returns>
        /// <param name="context">Context.</param>
        public UMAData.UMARecipe GetCachedRecipe(UMAContextBase context)
        {
            if (!cached || umaRecipe == null)
            {
                umaRecipe = new UMAData.UMARecipe();
                Load(umaRecipe, context);
#if !UNITY_EDITOR
#if UMA_ADDRESSABLES
                // don't cache addressables, as they can be unloaded.
                cached = false;
#else
                // do not cache in the editor
                cached = true;
#endif
#endif
            }

            return(umaRecipe);
        }
        /// <summary>
        /// Returns the recipe string as a DCSUniversalPackRecipe data model that can be used by any UMA
        /// </summary>
        /// <param name="context"></param>
        /// <param name="recipeToUnpack"></param>
        /// <param name="targetUTR">If set the wardrobeSet (if it exists) and the recipeType will assigned to UMATextRecipe assets fields (used by the Recipe Editor)</param>
        /// <returns></returns>
        public static DCSUniversalPackRecipe PackedLoadDCS(UMAContextBase context, string recipeToUnpack, UMATextRecipe targetUTR = null)
        {
            if ((recipeToUnpack == null) || (recipeToUnpack.Length == 0))
            {
                return(new DCSUniversalPackRecipe());
            }
            //first use the DCSRecipeChecker to check if this is a DCS recipe
            var typeInRecipe     = GetRecipesType(recipeToUnpack);
            var targetRecipeType = typeInRecipe != "Standard" ? typeInRecipe : (targetUTR != null ? targetUTR.recipeType : "Standard");

            if (targetUTR != null)
            {
                targetUTR.recipeType = targetRecipeType;
                if (RecipeHasWardrobeSet(recipeToUnpack))
                {
                    targetUTR.activeWardrobeSet = GetRecipesWardrobeSet(recipeToUnpack);
                }
            }
            //Right now the only recipeType that uses the DCSModel is "DynamicCharacterAvatar"
            DCSUniversalPackRecipe thisUnpackedUniversal = null;

            if (targetRecipeType == "DynamicCharacterAvatar" || targetRecipeType == "WardrobeCollection")
            {
                var thisUnpacked = JsonUtility.FromJson <DCSPackRecipe>(recipeToUnpack);
                thisUnpackedUniversal = new DCSUniversalPackRecipe(thisUnpacked);
            }
            else
            {
                var thisUnpacked = JsonUtility.FromJson <UMAPackRecipe>(recipeToUnpack);
                thisUnpackedUniversal = new DCSUniversalPackRecipe(thisUnpacked);
            }
            if (RecipeHasWardrobeSet(recipeToUnpack))
            {
                thisUnpackedUniversal.wardrobeSet = GetRecipesWardrobeSet(recipeToUnpack);
            }

            return(thisUnpackedUniversal);
        }
Пример #11
0
        public virtual void AddToContext(UMAContextBase context)
        {
            if (context == null)
            {
                return;
            }

            if (overlayData.Length > 0)
            {
#if UNITY_EDITOR
                UnityEditor.Undo.RecordObject(context, "Added overlays from asset collection");
#endif
                for (int i = 0; i < overlayData.Length; i++)
                {
                    context.AddOverlayAsset(overlayData[i]);
                }
            }
            if (slotData.Length > 0)
            {
#if UNITY_EDITOR
                UnityEditor.Undo.RecordObject(context, "Added slots from asset collection");
#endif
                for (int i = 0; i < slotData.Length; i++)
                {
                    context.AddSlotAsset(slotData[i]);
                }
            }
            if (raceData.Length > 0)
            {
#if UNITY_EDITOR
                UnityEditor.Undo.RecordObject(context, "Added races from asset collection");
#endif
                for (int i = 0; i < raceData.Length; i++)
                {
                    context.AddRace(raceData[i]);
                }
            }
        }
 /// <summary>
 /// Serialize the packed recipe.
 /// </summary>
 /// <param name="packedRecipe">Packed recipe.</param>
 /// <param name="context">Context.</param>
 public abstract void PackedSave(UMAPackRecipe packedRecipe, UMAContextBase context);
 /// <summary>
 /// Load serialized data into the packed recipe.
 /// </summary>
 /// <returns>The UMAPackRecipe.</returns>
 /// <param name="context">Context.</param>
 public abstract UMAPackRecipe PackedLoad(UMAContextBase context);
        public static bool UnpackRecipeVersion1(UMA.UMAData.UMARecipe umaRecipe, UMAPackRecipe umaPackRecipe, UMAContextBase context)
        {
            if (!UMAPackRecipe.ArrayHasData(umaPackRecipe.packedSlotDataList))
            {
                return(false);
            }

            umaRecipe.slotDataList = new SlotData[umaPackRecipe.packedSlotDataList.Length];

            umaRecipe.SetRace(context.GetRace(umaPackRecipe.race));

            umaRecipe.ClearDna();
            for (int dna = 0; dna < umaPackRecipe.packedDna.Count; dna++)
            {
                Type dnaType = UMADna.GetType(umaPackRecipe.packedDna[dna].dnaType);
                umaRecipe.AddDna(UMADna.LoadInstance(dnaType, umaPackRecipe.packedDna[dna].packedDna));
            }

            for (int i = 0; i < umaPackRecipe.packedSlotDataList.Length; i++)
            {
                if (UMAPackRecipe.SlotIsValid(umaPackRecipe.packedSlotDataList[i]))
                {
                    var tempSlotData = context.InstantiateSlot(umaPackRecipe.packedSlotDataList[i].slotID);
                    tempSlotData.overlayScale = umaPackRecipe.packedSlotDataList[i].overlayScale * 0.01f;
                    umaRecipe.slotDataList[i] = tempSlotData;

                    if (umaPackRecipe.packedSlotDataList[i].copyOverlayIndex == -1)
                    {
                        for (int overlay = 0; overlay < umaPackRecipe.packedSlotDataList[i].OverlayDataList.Length; overlay++)
                        {
                            Color tempColor;
                            Rect  tempRect;

                            if (UMAPackRecipe.ArrayHasData(umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].colorList))
                            {
                                tempColor = new Color(umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].colorList[0] / 255.0f, umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].colorList[1] / 255.0f, umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].colorList[2] / 255.0f, umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].colorList[3] / 255.0f);
                            }
                            else
                            {
                                tempColor = new Color(1.0f, 1.0f, 1.0f, 1.0f);
                            }

                            if (UMAPackRecipe.ArrayHasData(umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].rectList))
                            {
                                Rect originalRect = context.InstantiateOverlay(umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].overlayID).rect;
                                tempRect = new Rect(umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].rectList[0], umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].rectList[1], umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].rectList[2], umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].rectList[3]);

                                Vector2 aspectRatio = new Vector2(tempRect.width / originalRect.width, tempRect.height / originalRect.height);

                                tempRect = new Rect(tempRect.x / aspectRatio.x, tempRect.y / aspectRatio.y, tempRect.width / aspectRatio.x, tempRect.height / aspectRatio.y);
                            }
                            else
                            {
                                tempRect = new Rect(0, 0, 0, 0);
                            }

                            tempSlotData.AddOverlay(context.InstantiateOverlay(umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].overlayID));
                            tempSlotData.GetOverlay(tempSlotData.OverlayCount - 1).colorData.color = tempColor;
                            tempSlotData.GetOverlay(tempSlotData.OverlayCount - 1).rect            = tempRect;

                            if (UMAPackRecipe.ArrayHasData(umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].channelMaskList))
                            {
                                for (int channelAdjust = 0; channelAdjust < umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].channelMaskList.Length; channelAdjust++)
                                {
                                    packedOverlayData tempData = umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay];
                                    tempSlotData.GetOverlay(tempSlotData.OverlayCount - 1).SetColor(channelAdjust, new Color32((byte)tempData.channelMaskList[channelAdjust][0],
                                                                                                                               (byte)tempData.channelMaskList[channelAdjust][1],
                                                                                                                               (byte)tempData.channelMaskList[channelAdjust][2],
                                                                                                                               (byte)tempData.channelMaskList[channelAdjust][3]));
                                }
                            }

                            if (UMAPackRecipe.ArrayHasData(umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].channelAdditiveMaskList))
                            {
                                for (int channelAdjust = 0; channelAdjust < umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay].channelAdditiveMaskList.Length; channelAdjust++)
                                {
                                    packedOverlayData tempData = umaPackRecipe.packedSlotDataList[i].OverlayDataList[overlay];
                                    tempSlotData.GetOverlay(tempSlotData.OverlayCount - 1).SetAdditive(channelAdjust, new Color32((byte)tempData.channelAdditiveMaskList[channelAdjust][0],
                                                                                                                                  (byte)tempData.channelAdditiveMaskList[channelAdjust][1],
                                                                                                                                  (byte)tempData.channelAdditiveMaskList[channelAdjust][2],
                                                                                                                                  (byte)tempData.channelAdditiveMaskList[channelAdjust][3]));
                                }
                            }
                        }
                    }
                    else
                    {
                        tempSlotData.SetOverlayList(umaRecipe.slotDataList[umaPackRecipe.packedSlotDataList[i].copyOverlayIndex].GetOverlayList());
                    }
                }
            }
            return(true);
        }
        public static void UnpackRecipe(UMA.UMAData.UMARecipe umaRecipe, UMAPackRecipe umaPackRecipe, UMAContextBase context)
        {
            switch (umaPackRecipe.version)
            {
            case 3:
                UnpackRecipeVersion3(umaRecipe, umaPackRecipe, context);
                break;

            case 2:
                UnpackRecipeVersion2(umaRecipe, umaPackRecipe, context);
                break;

            case 1:
            default:
                if (UnpackRecipeVersion1(umaRecipe, umaPackRecipe, context))
                {
                    umaRecipe.MergeMatchingOverlays();
                }
                break;
            }
        }
        public static GameObject CreateEditorContext()
        {
            GameObject EditorUMAContextBase = null;

            if (UnityEditor.BuildPipeline.isBuildingPlayer)
            {
                return(null);
            }
            if (Application.isPlaying)
            {
                if (Debug.isDebugBuild)
                {
                    Debug.LogWarning("There was no UMAContext in this scene. Please add the UMA_DCS prefab to this scene before you try to generate an UMA.");
                }
                return(null);
            }

            if (Debug.isDebugBuild)
            {
                Debug.Log("UMA Recipe Editor created an UMAEditorContext to enable editing. This will auto delete once you have finished editing your recipe or you add the UMA_DCS prefab to this scene.");
            }

            //if there is already an EditorUMAContextBase use it
            if (UMAContextBase.FindInstance() != null)
            {
                if (UMAContextBase.FindInstance().gameObject.name == "UMAEditorContext")
                {
                    EditorUMAContextBase = UMAContextBase.FindInstance().gameObject;
                    //if the UMAContextBase itself is on this game object, it means this was created and not deleted by the previous version of 'CreateEditorContext'
                    //(The new version creates the UMAContextBase on a child game object called 'UMAContextBase' so that UMAContextBase.FindInstance can find it properly)
                    //so in this case delete all the components that would have been added from the found gameObject from the previous code
                    if (EditorUMAContextBase.GetComponent <UMAContextBase>())
                    {
                        UMAUtils.DestroySceneObject(EditorUMAContextBase.GetComponent <UMAContextBase>());                       //should also make the instance null again
                    }
                }
                else if (UMAContextBase.FindInstance().gameObject.transform.parent.gameObject.name == "UMAEditorContext")
                {
                    EditorUMAContextBase = UMAContextBase.FindInstance().gameObject.transform.parent.gameObject;
                }
            }
            else if (GameObject.Find("UMAEditorContext"))
            {
                EditorUMAContextBase = GameObject.Find("UMAEditorContext");
            }
            else
            {
                EditorUMAContextBase      = new GameObject();
                EditorUMAContextBase.name = "UMAEditorContext";
            }
            //Make this GameObject not show up in the scene or save
            EditorUMAContextBase.hideFlags = HideFlags.DontSave | HideFlags.NotEditable;
            //if this gameobject does not contain an UMAContextBase add it - we have to call it UMAContextBase because UMAContextBase.FindInstance searches for that game object
            var thisUMAContextBase = UMAContextBase.Instance = EditorUMAContextBase.GetComponentInChildren <UMAContextBase>();

            if (UMAContextBase.Instance == null)
            {
                var thisUMAContextBaseGO = new GameObject();
                thisUMAContextBaseGO.name             = "UMAContext";
                thisUMAContextBaseGO.transform.parent = EditorUMAContextBase.transform;
                thisUMAContextBase      = thisUMAContextBaseGO.AddComponent <UMAGlobalContext>();
                UMAContextBase.Instance = thisUMAContextBase;
            }
            return(EditorUMAContextBase);
        }
        private void GenerateLookups(UMAContextBase context, List <AssetItem> wardrobe)
        {
            float pos = 0.0f;
            float inc = 1.0f / wardrobe.Count;

            // Get the slots, overlays, textures.
            // calculate the number of references for each of them.
            // Map the usage
            foreach (AssetItem recipeItem in wardrobe)
            {
                UMATextRecipe uwr  = recipeItem.Item as UMATextRecipe;
                int           iPos = Mathf.CeilToInt(pos);
                EditorUtility.DisplayProgressBar("Generating", "Calculating Usage: " + uwr.name, iPos);

                // todo: cache this
                UMAData.UMARecipe ur = UMAAssetIndexer.Instance.GetRecipe(uwr, context);

                if (ur.slotDataList == null)
                {
                    continue;
                }

                foreach (SlotData sd in ur.slotDataList)
                {
                    if (sd == null)
                    {
                        continue;
                    }

                    AssetItem ai = UMAAssetIndexer.Instance.GetAssetItem <SlotDataAsset>(sd.slotName);

                    if (ai != null && ai.IsAlwaysLoaded == false)
                    {
                        // is this a utility slot? if so, we need to not delete it as an orphan.
                        if (sd.asset.isUtilitySlot)
                        {
                            ai.IsAlwaysLoaded = true;
                        }
                    }

                    //if (!(ai != null && ai.IsAlwaysLoaded))
                    //{
                    //AddToTracker = false;
                    //}
                    //else
                    //{
                    int slotInstance = sd.asset.GetInstanceID();

                    if (!SlotTracker.ContainsKey(slotInstance))
                    {
                        ai.IsAddressable = true;
                        SlotTracker.Add(slotInstance, new List <UMATextRecipe>());
                    }
                    SlotTracker[slotInstance].Add(uwr);
                    if (!AddressLookup.ContainsKey(slotInstance))
                    {
                        AddressLookup.Add(slotInstance, "Slt-" + sd.slotName);
                    }
                    //}

                    List <OverlayData> odList = sd.GetOverlayList();

                    foreach (OverlayData od in odList)
                    {
                        if (od == null)
                        {
                            continue;
                        }


                        /* = GetAssetItem<OverlayDataAsset>(od.overlayName);
                         *
                         * if (ai != null && ai.IsAlwaysLoaded)
                         * {
                         *  continue;
                         * }*/

                        int OverlayInstance = od.asset.GetInstanceID();

                        if (!OverlayTracker.ContainsKey(OverlayInstance))
                        {
                            OverlayTracker.Add(OverlayInstance, new List <UMATextRecipe>());
                        }
                        OverlayTracker[OverlayInstance].Add(uwr);
                        if (!AddressLookup.ContainsKey(OverlayInstance))
                        {
                            ai.IsAddressable = true;
                            AddressLookup.Add(OverlayInstance, "Ovl-" + od.overlayName);
                        }
                        foreach (Texture tx in od.textureArray)
                        {
                            if (tx == null)
                            {
                                continue;
                            }
                            int TextureID = tx.GetInstanceID();
                            if (!TextureTracker.ContainsKey(TextureID))
                            {
                                TextureTracker.Add(TextureID, new List <UMATextRecipe>());
                            }
                            TextureTracker[TextureID].Add(uwr);
                            if (!AddressLookup.ContainsKey(TextureID))
                            {
                                AddressLookup.Add(TextureID, "Tex-" + tx.name);
                            }
                        }
                    }
                }
                pos += inc;
            }
        }
        /// <summary>
        /// Load data into the specified UMA recipe.
        /// </summary>
        /// <param name="umaRecipe">UMA recipe.</param>
        /// <param name="context">Context.</param>
        public override void Load(UMA.UMAData.UMARecipe umaRecipe, UMAContextBase context)
        {
            var packedRecipe = PackedLoad(context);

            UnpackRecipe(umaRecipe, packedRecipe, context);
        }
Пример #19
0
        public static GameObject CreateEditorContext()
        {
            GameObject EditorUMAContextBase = null;

            if (UnityEditor.BuildPipeline.isBuildingPlayer)
            {
                return(null);
            }
            if (Application.isPlaying)
            {
                if (Debug.isDebugBuild)
                {
                    Debug.LogWarning("There was no UMAContext in this scene. Please add the UMA context prefab  to this scene before you try to generate an UMA.");
                }
                return(null);
            }

            if (Debug.isDebugBuild)
            {
                Debug.Log("UMA Recipe Editor created an UMAEditorContext to enable editing. This will auto delete once you have finished editing your recipe or you add a UMA prefab with a context to this scene.");
            }

            //if there is already an EditorUMAContextBase use it
            if (UMAContextBase.FindInstance() != null)
            {
                if (UMAContextBase.FindInstance().gameObject.name == "UMAEditorContext")
                {
                    EditorUMAContextBase = UMAContextBase.FindInstance().gameObject;
                    //if the UMAContextBase itself is on this game object, it means this was created and not deleted by the previous version of 'CreateEditorContext'
                    //(The new version creates the UMAContextBase on a child game object called 'UMAContextBase' so that UMAContextBase.FindInstance can find it properly)
                    //so in this case delete all the components that would have been added from the found gameObject from the previous code
                    if (EditorUMAContextBase.GetComponent <UMAContextBase>())
                    {
                        UMAUtils.DestroySceneObject(EditorUMAContextBase.GetComponent <UMAContextBase>());                       //should also make the instance null again
                    }
                }
                else if (UMAContextBase.FindInstance().gameObject.transform.parent.gameObject.name == "UMAEditorContext")
                {
                    EditorUMAContextBase = UMAContextBase.FindInstance().gameObject.transform.parent.gameObject;
                }
            }
            else if (GameObject.Find("UMAEditorContext"))
            {
                EditorUMAContextBase = GameObject.Find("UMAEditorContext");
            }
            else
            {
                EditorUMAContextBase      = new GameObject();
                EditorUMAContextBase.name = "UMAEditorContext";
            }
            //Make this GameObject not show up in the scene or save
            EditorUMAContextBase.hideFlags = HideFlags.DontSave | HideFlags.NotEditable;
            //if this gameobject does not contain an UMAContextBase add it - we have to call it UMAContextBase because UMAContextBase.FindInstance searches for that game object
            var context = UMAContextBase.Instance = EditorUMAContextBase.GetComponentInChildren <UMAContextBase>();

            if (UMAContextBase.Instance == null)
            {
                var GO = new GameObject();
                GO.name             = "UMAContext";
                GO.transform.parent = EditorUMAContextBase.transform;
                context             = GO.AddComponent <UMAGlobalContext>();
                GO.AddComponent <UMADefaultMeshCombiner>();

                var gen = GO.AddComponent <UMAGenerator>();
                gen.fitAtlas               = true;
                gen.SharperFitTextures     = true;
                gen.AtlasOverflowFitMethod = UMAGeneratorBase.FitMethod.BestFitSquare;
                gen.convertRenderTexture   = false;
                gen.editorAtlasResolution  = 1024;
                gen.InitialScaleFactor     = 2;
                gen.collectGarbage         = false;
                gen.IterationCount         = 1;
                gen.fastGeneration         = true;
                gen.processAllPending      = false;
                gen.NoCoroutines           = true;
                UMAContextBase.Instance    = context;
            }
            return(EditorUMAContextBase);
        }
        public void GenerateAddressables()
        {
            try
            {
                //**********************************************************************************************
                //*  Clear out the old data
                //**********************************************************************************************
                SlotTracker    = new Dictionary <int, List <UMATextRecipe> >();
                OverlayTracker = new Dictionary <int, List <UMATextRecipe> >();
                TextureTracker = new Dictionary <int, List <UMATextRecipe> >();
                GroupTracker   = new Dictionary <int, AddressableAssetGroup>();

                ClearAddressableFlags(typeof(SlotDataAsset));
                ClearAddressableFlags(typeof(OverlayDataAsset));

                // Will generate an editor context if needed.
                UMAContextBase context = UMAAssetIndexer.Instance.GetContext();

                // Create the shared group that has each item packed separately.
                AddressableAssetGroup sharedGroup = AddressableUtility.AddressableSettings.CreateGroup(SharedGroupName, false, false, true, AddressableUtility.AddressableSettings.DefaultGroup.Schemas);
                sharedGroup.GetSchema <BundledAssetGroupSchema>().BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackSeparately;

                List <UMATextRecipe> theRecipes = new List <UMATextRecipe>();

                //**********************************************************************************************
                //*  Add Races
                //**********************************************************************************************

                System.Type theType = UMAAssetIndexer.Instance.GetIndexedType(typeof(RaceData));
                var         races   = UMAAssetIndexer.Instance.GetAssetDictionary(theType).Values;

                foreach (AssetItem ai in races)
                {
                    RaceData race = ai.Item as RaceData;
                    if (race == null)
                    {
                        Debug.Log("Invalid race found!");
                        continue;
                    }
                    if (race.baseRaceRecipe as UMATextRecipe == null)
                    {
                        Debug.Log("Invalid base race recipe on race: " + race.raceName);
                    }
                    theRecipes.Add(race.baseRaceRecipe as UMATextRecipe);
                    if (ai.IsAlwaysLoaded)
                    {
                        AssetItem recipe = UMAAssetIndexer.Instance.GetAssetItem <UMATextRecipe>(race.baseRaceRecipe.name);
                        recipe.IsAlwaysLoaded = true;

                        List <AssetItem> recipeItems = UMAAssetIndexer.Instance.GetAssetItems(race.baseRaceRecipe as UMAPackedRecipeBase, true);
                        foreach (AssetItem recipeitem in recipeItems)
                        {
                            recipeitem.IsAlwaysLoaded = true;
                        }
                    }
                }



                var theRecipeItems = GetAddressableRecipes();

                GenerateCollectionLabels();

                GenerateLookups(context, theRecipeItems);

                float pos = 0.0f;
                float inc = 1.0f / theRecipes.Count;

                const string tprefix = "UTR_";
                const string wprefix = "UWR_";

                // Create the Addressable groups
                foreach (AssetItem recipeItem in theRecipeItems)
                {
                    UMATextRecipe uwr  = recipeItem.Item as UMATextRecipe;
                    int           iPos = Mathf.CeilToInt(pos);
                    EditorUtility.DisplayProgressBar("Generating", "Creating Group: " + uwr.name, iPos);
                    Debug.Log("Generating group: " + uwr.name);
                    string groupName;
                    if (uwr is UMAWardrobeRecipe)
                    {
                        groupName = wprefix + uwr.name;
                    }
                    else
                    {
                        groupName = tprefix + uwr.name;
                    }
                    AddressableAssetGroup recipeGroup = AddressableUtility.AddressableSettings.CreateGroup(groupName, false, false, true, AddressableUtility.AddressableSettings.DefaultGroup.Schemas);
                    recipeGroup.GetSchema <BundledAssetGroupSchema>().BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogether;

                    if (GroupTracker.ContainsKey(uwr.GetInstanceID()))
                    {
                        Debug.Log("Group already exists????? " + uwr.name);
                        continue;
                    }
                    GroupTracker.Add(uwr.GetInstanceID(), recipeGroup);
                    pos += inc;
                }

                AddAddressableAssets(SlotTracker, sharedGroup);
                AddAddressableAssets(OverlayTracker, sharedGroup);
                AddAddressableAssets(TextureTracker, sharedGroup);

                AssignAddressableInformation();

                ReleaseReferences(UMAAssetIndexer.Instance.GetIndexedType(typeof(SlotDataAsset)));
                ReleaseReferences(UMAAssetIndexer.Instance.GetIndexedType(typeof(OverlayDataAsset)));

                CleanupAddressables(true);
            }
            finally
            {
                EditorUtility.ClearProgressBar();
                UMAAssetIndexer.Instance.DestroyEditorUMAContextBase();
                UMAAssetIndexer.Instance.ForceSave();
            }
        }
Пример #21
0
 /// <summary>
 /// Serialize recipeString data into packed recipe.
 /// </summary>
 /// <param name="packedRecipe">Packed recipe.</param>
 /// <param name="context">Context.</param>
 public override void PackedSave(UMAPackedRecipeBase.UMAPackRecipe packedRecipe, UMAContextBase context)
 {
     recipeString = JsonUtility.ToJson(packedRecipe);
 }
 /// <summary>
 /// Creates a temporary UMAContextBase for use when editing recipes when the open Scene does not have an UMAContextBase or libraries set up
 /// </summary>
 ///
 public override UMAContextBase CreateEditorContext()
 {
     UMAContextBase.CreateEditorContext();
     return(UMAContextBase.Instance);
 }
 /// <summary>
 /// Internal call to static PackedLoadDCS which uses the assets string and object and returns a DCSUniversalPackRecipe data model that can be used by any UMA
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 protected DCSUniversalPackRecipe PackedLoadDCSInternal(UMAContextBase context /*, string recipeToUnpack*/)
 {
     return(PackedLoadDCS(context, recipeString, this));
 }