// ================================================================================
        //  import methods
        // --------------------------------------------------------------------------------

        public void ImportAssets(DefaultAsset[] assets, ImportAnimatorController importAnimatorController = ImportAnimatorController.None)
        {
            List <AnimationImportJob> jobs = new List <AnimationImportJob>();

            foreach (var asset in assets)
            {
                string assetPath = AssetDatabase.GetAssetPath(asset);
                if (!IsValidAsset(assetPath))
                {
                    continue;
                }

                AnimationImportJob job = CreateAnimationImportJob(assetPath);
                job.importAnimatorController = importAnimatorController;
                jobs.Add(job);
            }

            Import(jobs.ToArray());
        }
        /// <summary>
        /// can be used by custom import pipeline
        /// </summary>
        public ImportedAnimationSheet ImportSpritesAndAnimationSheet(string assetPath, string additionalCommandLineArguments = null)
        {
            if (!IsValidAsset(assetPath))
            {
                return(null);
            }

            // making sure config is valid
            if (sharedData == null)
            {
                LoadOrCreateUserConfig();
            }

            // create a job
            AnimationImportJob job = CreateAnimationImportJob(assetPath, additionalCommandLineArguments);

            job.createUnityAnimations = false;

            return(ImportJob(job));
        }
        // ================================================================================
        //  automatic ReImport
        // --------------------------------------------------------------------------------

        /// <summary>
        /// will be called by the AssetPostProcessor
        /// </summary>
        public void AutomaticReImport(string[] assetPaths)
        {
            if (sharedData == null)
            {
                LoadOrCreateUserConfig();
            }

            List <AnimationImportJob> jobs = new List <AnimationImportJob>();

            foreach (var assetPath in assetPaths)
            {
                if (string.IsNullOrEmpty(assetPath))
                {
                    continue;
                }

                if (HandleCustomReImport != null && HandleCustomReImport(assetPath))
                {
                    continue;
                }

                AnimationImportJob job = CreateAnimationImportJob(assetPath);
                if (job != null)
                {
                    if (HasExistingAnimatorController(assetPath))
                    {
                        job.importAnimatorController = ImportAnimatorController.AnimatorController;
                    }
                    else if (HasExistingAnimatorOverrideController(assetPath))
                    {
                        job.importAnimatorController      = ImportAnimatorController.AnimatorOverrideController;
                        job.useExistingAnimatorController = true;
                    }

                    jobs.Add(job);
                }
            }

            Import(jobs.ToArray());
        }
        private ImportedAnimationSheet ImportJob(AnimationImportJob job)
        {
            job.SetProgress(0);

            IAnimationImporterPlugin importer       = _importerPlugins[GetExtension(job.fileName)];
            ImportedAnimationSheet   animationSheet = importer.Import(job, sharedData);

            job.SetProgress(0.3f);

            if (animationSheet != null)
            {
                animationSheet.assetDirectory = job.assetDirectory;
                animationSheet.name           = job.name;

                animationSheet.ApplySpriteNamingScheme(sharedData.spriteNamingScheme);

                CreateSprites(animationSheet, job);

                job.SetProgress(0.6f);

                if (job.createUnityAnimations)
                {
                    CreateAnimations(animationSheet, job);

                    job.SetProgress(0.8f);

                    if (job.importAnimatorController == ImportAnimatorController.AnimatorController)
                    {
                        CreateAnimatorController(animationSheet);
                    }
                    else if (job.importAnimatorController == ImportAnimatorController.AnimatorOverrideController)
                    {
                        CreateAnimatorOverrideController(animationSheet, job.useExistingAnimatorController);
                    }
                }
            }

            return(animationSheet);
        }
Example #5
0
        // ================================================================================
        //  import methods
        // --------------------------------------------------------------------------------

        public void ImportAssets(DefaultAsset[] assets, ImportAnimatorController importAnimatorController = ImportAnimatorController.None)
        {
            List <AnimationImportJob> jobs = new List <AnimationImportJob>();

            foreach (var asset in assets)
            {
                string assetPath = AssetDatabase.GetAssetPath(asset);
                if (!IsValidAsset(assetPath))
                {
                    continue;
                }

                // DDobyns change to support adding to existing Animator Override Controller on manual import
                AnimationImportJob job = CreateAnimationImportJob(assetPath);
                if (job != null)
                {
                    if (HasExistingAnimatorController(assetPath))
                    {
                        job.importAnimatorController = ImportAnimatorController.AnimatorController;
                    }
                    else if (HasExistingAnimatorOverrideController(assetPath))
                    {
                        job.importAnimatorController      = ImportAnimatorController.AnimatorOverrideController;
                        job.useExistingAnimatorController = true;
                    }

                    jobs.Add(job);
                }



                //            AnimationImportJob job = CreateAnimationImportJob(assetPath);
                //job.importAnimatorController = importAnimatorController;
                //            //job.useExistingAnimatorController = true;   /// DDobyns test for adding to existing
                //jobs.Add(job);
            }

            Import(jobs.ToArray());
        }
Example #6
0
        private void CreateAnimatorOverrideController(ImportedAnimationSheet animations, AnimationImportJob job)
        {
            AnimatorOverrideController overrideController;

            string directory = sharedData.animationControllersTargetLocation.GetAndEnsureTargetDirectory(job.assetPath);

            string pathForOverrideController;

            // check if override controller already exists; use this to not loose any references to this in other assets
            if (sharedData.namingScheme == NamingScheme.ItsName)
            {
                pathForOverrideController = $"{directory}/animatorController.overrideController";
            }
            else
            {
                pathForOverrideController = $"{directory}/{animations.name}.overrideController";
            }
            overrideController = AssetDatabase.LoadAssetAtPath <AnimatorOverrideController>(pathForOverrideController);

            RuntimeAnimatorController baseController = _baseController;

            if (job.useExistingAnimatorController && overrideController.runtimeAnimatorController != null)
            {
                baseController = overrideController.runtimeAnimatorController;
            }

            if (baseController != null)
            {
                if (overrideController == null)
                {
                    overrideController = new AnimatorOverrideController();
                    AssetDatabase.CreateAsset(overrideController, pathForOverrideController);
                }

                overrideController.runtimeAnimatorController = baseController;

                // set override clips
#if UNITY_5_6_OR_NEWER
                var clipPairs = new List <KeyValuePair <AnimationClip, AnimationClip> >(overrideController.overridesCount);
                overrideController.GetOverrides(clipPairs);

                foreach (var pair in clipPairs)
                {
                    string        animationName = pair.Key.name;
                    AnimationClip clip          = animations.GetClipOrSimilar(animationName);
                    overrideController[animationName] = clip;
                }
#else
                var clipPairs = overrideController.clips;
                for (int i = 0; i < clipPairs.Length; i++)
                {
                    string        animationName = clipPairs[i].originalClip.name;
                    AnimationClip clip          = animations.GetClipOrSimilar(animationName);
                    clipPairs[i].overrideClip = clip;
                }
                overrideController.clips = clipPairs;
#endif

                EditorUtility.SetDirty(overrideController);
            }
            else
            {
                Debug.LogWarning("No Animator Controller found as a base for the Override Controller");
            }
        }
        private void CreateSprites(ImportedAnimationSheet animationSheet, AnimationImportJob job)
        {
            if (animationSheet == null)
            {
                return;
            }
            var spriteInfos = new List <NamedSpriteInfo>();

            animationSheet.CreateSpriteInfos(
                in sharedData.customPivotSettings,
                spriteInfos
                );

            var siMap   = new Dictionary <uint, NamedSpriteInfo>();
            var nameMap = new Dictionary <string, string>();

            var outputTexs = new Dictionary <Texture2D, SpriteMetaData[]>();

            if (sharedData.doTrim)
            {
                var srcTex = animationSheet.srcTex;
                if (srcTex == null)
                {
                    return; //?
                }

                var trimIndexList = new List <uint>();
                for (int i = 0; i < spriteInfos.Count; ++i)
                {
                    job.SetProgress(0.4f + i / (10.0f * spriteInfos.Count), "trimming sprite " + i.ToString());
                    var trimmed    = spriteInfos[i].info.Trim(sharedData.trimColor, sharedData.trimMargin.x, sharedData.trimMargin.y);
                    var trimmedCrc = trimmed.GetCrc32();
                    if (!siMap.ContainsKey(trimmedCrc))
                    {
                        siMap[trimmedCrc] = new NamedSpriteInfo {
                            name = spriteInfos[i].name,
                            info = trimmed,
                        };
                        trimIndexList.Add(trimmedCrc);
                    }
                    nameMap[spriteInfos[i].name] = siMap[trimmedCrc].name;
                }

                trimIndexList.Sort((lhsi, rhsi) => {
                    var lhs = siMap[lhsi].info.frame;
                    var rhs = siMap[rhsi].info.frame;
                    if (lhs.width == rhs.width)
                    {
                        return(lhs.height - rhs.height);
                    }
                    return(rhs.width - lhs.width);

                    // return (rhs.width + rhs.height) - (lhs.width + lhs.height);
                });

                var boxs = new Luxko.Geometry.SkylinePacker.Box[trimIndexList.Count];
                for (int i = 0; i < trimIndexList.Count; ++i)
                {
                    var spriteInfo = siMap[trimIndexList[i]].info;
                    boxs[i].w = spriteInfo.frame.width + sharedData.trimSpacing.x;
                    boxs[i].h = spriteInfo.frame.height + sharedData.trimSpacing.y;
                }

                job.SetProgress(0.5f, "caculate packing info");
                var packOutput = new Luxko.Geometry.SkylinePacker.Output[trimIndexList.Count];
                var packBin    = new Luxko.Geometry.SkylinePacker.Box {
                    w = sharedData.trimTexSize.x, h = sharedData.trimTexSize.y
                };

                var sky = new Luxko.Geometry.SkylinePacker.Sky(packBin, sharedData.PackSpreadFactor > 0 ? sharedData.PackSpreadFactor : (int)(packBin.h * 0.75f), boxs);
                for (int i = 0; i < boxs.Length; ++i)
                {
                    sky.PackNext(out packOutput[i]);
                }

                var sheetBuf = new List <KeyValuePair <Texture2D, List <SpriteMetaData> > >();
                for (int i = 0; i < packOutput.Length; ++i)
                {
                    while (sheetBuf.Count <= packOutput[i].binIndex)
                    {
                        var newTex = new Texture2D(sharedData.trimTexSize.x, sharedData.trimTexSize.y, TextureFormat.RGBA32, false); // TODO: proper linear flag
                        ClearTexture(newTex, Color.clear);
                        sheetBuf.Add(new KeyValuePair <Texture2D, List <SpriteMetaData> >(
                                         newTex, new List <SpriteMetaData>()
                                         ));
                    }

                    var tSheet = sheetBuf[packOutput[i].binIndex];
                    var ti     = new SpritePacker.SpriteInfo {
                        tex   = tSheet.Key,
                        frame = new RectInt(packOutput[i].pos.x, packOutput[i].pos.y, 0, 0)
                    };
                    var tis = siMap[trimIndexList[packOutput[i].boxIndex]];
                    job.SetProgress(0.55f + i / (20.0f * trimIndexList.Count), string.Format("packing {0} at {1} to {2}", tis.name, tis.info.frame, ti.frame.position));
                    tis.info.TryCopyTo(ref ti);
                    tSheet.Value.Add(new SpriteMetaData {
                        name      = tis.name,
                        rect      = new Rect(ti.frame.x, ti.frame.y, ti.frame.width, ti.frame.height),
                        alignment = (int)SpriteAlignment.Custom,
                        pivot     = ti.pivotN,
                    });
                }
                foreach (var kv in sheetBuf)
                {
                    outputTexs.Add(kv.Key, kv.Value.ToArray());
                }

                Texture2D.DestroyImmediate(srcTex, true);
            }
            else
            {
                var targetTex = animationSheet.srcTex;
                if (spriteInfos.Count > 0)
                {
                    var smds = new SpriteMetaData[spriteInfos.Count];
                    for (int si = 0; si < spriteInfos.Count; ++si)
                    {
                        smds[si] = new SpriteMetaData {
                            name      = spriteInfos[si].name,
                            rect      = new Rect(spriteInfos[si].info.frame.x, spriteInfos[si].info.frame.y, spriteInfos[si].info.frame.width, spriteInfos[si].info.frame.height),
                            alignment = (int)SpriteAlignment.Custom,
                            pivot     = spriteInfos[si].info.pivotN,
                        };
                    }

                    outputTexs.Add(targetTex, smds);
                    spriteInfos.Clear();
                }
            }

            int kvi        = 0;
            var spriteDict = new Dictionary <string, Sprite>();

            foreach (var kv in outputTexs)
            {
                job.SetProgress(0.6f + 0.1f * (kvi / (float)outputTexs.Count), "saving textures " + kvi);
                string imgPath;
                if (kvi <= 0)
                {
                    imgPath = string.Format("{0}/{1}.png", job.directoryPathForSprites, job.name);
                }
                else
                {
                    imgPath = string.Format("{0}/{1}_{2}.png", job.directoryPathForSprites, job.name, kvi);
                }
                kvi++;

                SaveAsPng(kv.Key, imgPath);

                AssetDatabase.Refresh();
                AssetDatabase.ImportAsset(imgPath, ImportAssetOptions.ForceUpdate);

                var importer = AssetImporter.GetAtPath(imgPath) as TextureImporter;
                importer.textureType         = TextureImporterType.Sprite;
                importer.spritePixelsPerUnit = sharedData.spritePixelsPerUnit;
                importer.mipmapEnabled       = false;
                importer.filterMode          = FilterMode.Point;
                importer.textureCompression  = TextureImporterCompression.Uncompressed;
                // TODO: smart update: how to keep old references alive?
                importer.spritesheet        = kv.Value;
                importer.spriteImportMode   = SpriteImportMode.Multiple;
                importer.maxTextureSize     = 2048;
                importer.textureCompression = TextureImporterCompression.CompressedHQ;

                EditorUtility.SetDirty(importer);

                importer.SaveAndReimport();

                AssetDatabase.ImportAsset(imgPath, ImportAssetOptions.ForceUpdate);

                var assets = AssetDatabase.LoadAllAssetsAtPath(imgPath);

                foreach (var item in assets)
                {
                    if (item is Sprite)
                    {
                        var sprite = (Sprite)item;
                        spriteDict[sprite.name] = sprite;
                    }
                }
            }

            if (nameMap.Count != 0)
            {
                var replaceMap = new Dictionary <string, Sprite>();
                foreach (var kv in nameMap)
                {
                    replaceMap[kv.Key] = spriteDict[kv.Value];
                }
                spriteDict = replaceMap;
            }
            foreach (var kv in outputTexs)
            {
                Texture2D.DestroyImmediate(kv.Key);
            }
            outputTexs.Clear();
            animationSheet.ApplyCreatedSprites(spriteDict);
        }