public static void UpdateBlendModeMaterials(SkeletonDataAsset skeletonDataAsset, ref SkeletonData skeletonData,
                                                    bool upgradeFromModifierAssets = ShallUpgradeBlendModeMaterials)
        {
            TemplateMaterials templateMaterials = new TemplateMaterials();
            bool anyMaterialsChanged            = ClearUndesiredMaterialEntries(skeletonDataAsset);

            var blendModesModifierAsset = FindBlendModeMaterialsModifierAsset(skeletonDataAsset);

            if (blendModesModifierAsset)
            {
                if (upgradeFromModifierAssets)
                {
                    TransferSettingsFromModifierAsset(blendModesModifierAsset,
                                                      skeletonDataAsset, templateMaterials);
                    UpdateBlendmodeMaterialsRequiredState(skeletonDataAsset, skeletonData);
                }
                else
                {
                    return;
                }
            }
            else
            {
                if (!UpdateBlendmodeMaterialsRequiredState(skeletonDataAsset, skeletonData))
                {
                    return;
                }
                AssignPreferencesTemplateMaterials(templateMaterials);
            }
            bool success = CreateAndAssignMaterials(skeletonDataAsset, templateMaterials, ref anyMaterialsChanged);

            if (success)
            {
                if (blendModesModifierAsset != null)
                {
                    RemoveObsoleteModifierAsset(blendModesModifierAsset, skeletonDataAsset);
                }
            }

            skeletonDataAsset.Clear();
            skeletonData = skeletonDataAsset.GetSkeletonData(true);
            if (anyMaterialsChanged)
            {
                ReloadSceneSkeletons(skeletonDataAsset);
            }
            AssetDatabase.SaveAssets();
        }
 protected static void AssignPreferencesTemplateMaterials(TemplateMaterials templateMaterials)
 {
     templateMaterials.multiplyTemplate = SpineEditorUtilities.Preferences.BlendModeMaterialMultiply;
     templateMaterials.screenTemplate   = SpineEditorUtilities.Preferences.BlendModeMaterialScreen;
     templateMaterials.additiveTemplate = SpineEditorUtilities.Preferences.BlendModeMaterialAdditive;
 }
        protected static bool CreateAndAssignMaterials(SkeletonDataAsset skeletonDataAsset,
                                                       TemplateMaterials templateMaterials, ref bool anyReplacementMaterialsChanged)
        {
            bool anyCreationFailed     = false;
            var  blendModeMaterials    = skeletonDataAsset.blendModeMaterials;
            bool applyAdditiveMaterial = blendModeMaterials.applyAdditiveMaterial;

            var skinEntries = new List <Skin.SkinEntry>();

            skeletonDataAsset.Clear();
            skeletonDataAsset.isUpgradingBlendModeMaterials = true;
            SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(true);

            var slotsItems = skeletonData.Slots.Items;

            for (int slotIndex = 0, slotCount = skeletonData.Slots.Count; slotIndex < slotCount; slotIndex++)
            {
                var slot = slotsItems[slotIndex];
                if (slot.BlendMode == BlendMode.Normal)
                {
                    continue;
                }
                if (!applyAdditiveMaterial && slot.BlendMode == BlendMode.Additive)
                {
                    continue;
                }

                List <BlendModeMaterials.ReplacementMaterial> replacementMaterials = null;
                Material materialTemplate = null;
                string   materialSuffix   = null;
                switch (slot.BlendMode)
                {
                case BlendMode.Multiply:
                    replacementMaterials = blendModeMaterials.multiplyMaterials;
                    materialTemplate     = templateMaterials.multiplyTemplate;
                    materialSuffix       = MATERIAL_SUFFIX_MULTIPLY;
                    break;

                case BlendMode.Screen:
                    replacementMaterials = blendModeMaterials.screenMaterials;
                    materialTemplate     = templateMaterials.screenTemplate;
                    materialSuffix       = MATERIAL_SUFFIX_SCREEN;
                    break;

                case BlendMode.Additive:
                    replacementMaterials = blendModeMaterials.additiveMaterials;
                    materialTemplate     = templateMaterials.additiveTemplate;
                    materialSuffix       = MATERIAL_SUFFIX_ADDITIVE;
                    break;
                }

                skinEntries.Clear();
                foreach (var skin in skeletonData.Skins)
                {
                    skin.GetAttachments(slotIndex, skinEntries);
                }

                foreach (var entry in skinEntries)
                {
                    var renderableAttachment = entry.Attachment as IHasRendererObject;
                    if (renderableAttachment != null)
                    {
                        var  originalRegion    = (AtlasRegion)renderableAttachment.RendererObject;
                        bool replacementExists = replacementMaterials.Exists(
                            replacement => replacement.pageName == originalRegion.page.name);
                        if (!replacementExists)
                        {
                            bool createdNewMaterial;
                            var  replacement = CreateOrLoadReplacementMaterial(originalRegion, materialTemplate, materialSuffix, out createdNewMaterial);
                            if (replacement != null)
                            {
                                replacementMaterials.Add(replacement);
                                anyReplacementMaterialsChanged = true;
                                if (createdNewMaterial)
                                {
                                    Debug.Log(string.Format("Created blend mode Material '{0}' for SkeletonDataAsset '{1}'.",
                                                            replacement.material.name, skeletonDataAsset), replacement.material);
                                }
                            }
                            else
                            {
                                Debug.LogError(string.Format("Failed creating blend mode Material for SkeletonDataAsset '{0}'," +
                                                             " atlas page '{1}', template '{2}'.",
                                                             skeletonDataAsset.name, originalRegion.page.name, materialTemplate.name),
                                               skeletonDataAsset);
                                anyCreationFailed = true;
                            }
                        }
                    }
                }
            }

            skeletonDataAsset.isUpgradingBlendModeMaterials = false;
            EditorUtility.SetDirty(skeletonDataAsset);
            return(!anyCreationFailed);
        }
        protected static void TransferSettingsFromModifierAsset(BlendModeMaterialsAsset modifierAsset,
                                                                SkeletonDataAsset skeletonDataAsset, TemplateMaterials templateMaterials)
        {
            skeletonDataAsset.blendModeMaterials.TransferSettingsFrom(modifierAsset);

            templateMaterials.multiplyTemplate = modifierAsset.multiplyMaterialTemplate;
            templateMaterials.screenTemplate   = modifierAsset.screenMaterialTemplate;
            templateMaterials.additiveTemplate = modifierAsset.additiveMaterialTemplate;
        }