Exemple #1
0
        private GeneratedClip[] FinalizeAnimationClips(AsepriteFileInfo aseInfo, List <AnimationClip> clips)
        {
            m_clipCount = clips.Count;

            var previousGeneratedClips = new Dictionary <string, GeneratedClip>();

            foreach (var generatedClip in m_generatedClips)
            {
                previousGeneratedClips.Add(generatedClip.name, generatedClip);
            }

            var newGeneratedClips = new List <GeneratedClip>(m_clipCount);

            for (int i = 0; i < m_clipCount; i++)
            {
                AnimationClip clip    = clips[i];
                string        tagName = aseInfo.spriteSheetData.meta.frameTags[i].name;

                bool clipDoesExist = previousGeneratedClips.TryGetValue(tagName, out GeneratedClip clipData);

                if (clipDoesExist)
                {
                    clipData.name = tagName;
                    clipData.clip = clipData.createMode != GeneratedClip.CreateMode.Merge ? clip : null;
                }
                else
                {
                    clipData = GeneratedClip.Create(tagName, clip);
                }

                newGeneratedClips.Add(clipData);
            }

            return(newGeneratedClips.ToArray());
        }
Exemple #2
0
        private void GenerateAssets(Settings settings, AsepriteFileInfo aseInfo, AssetImportContext context)
        {
            string atlasPath = $"{aseInfo.absoluteDirectoryPath}/{aseInfo.title}_aseprite.png";
            string dataPath  = $"{aseInfo.absoluteDirectoryPath}/{aseInfo.title}_aseprite.json";

            // Create a temporary valid JSON file so Aseprite has something to write into
            // The file will be deleted after the json data is transferred to the meta file of the generated atlas
            File.WriteAllText(dataPath, "{}");

            // Use Aseprite to build an atlas from the file and generate accompanying JSON data
            AsepriteCLI.Run(
                "--batch",
                "--debug",
                $"\"{aseInfo.absolutePath}\"",
                "--filename-format {title}_{tag}-{tagframe}",
                "--sheet-type packed",
                "--inner-padding 1",
                "--trim",
                $"--sheet \"{atlasPath}\"",
                "--list-tags",
                "--format json-array",
                $"--data \"{dataPath}\""
                );

            // Get the JSON data generated by Aseprite, then delete the temp file
            aseInfo.spriteSheetData = JsonUtility.FromJson <SpriteSheetData>(File.ReadAllText(dataPath));
            File.Delete(dataPath);

            // Create Texture2D from Aseprite atlas, then delete the temp file
            m_atlas = CreateSpriteAtlasTexture(
                aseInfo.spriteSheetData.meta.size.w,
                aseInfo.spriteSheetData.meta.size.h,
                File.ReadAllBytes(atlasPath)
                );
            File.Delete(atlasPath);

            // Create Sprites from sheet data
            List <Sprite> sprites = CreateSpritesForAtlas(
                m_atlas,
                aseInfo.spriteSheetData
                );

            m_spriteCount = sprites.Count;

            // Create AnimationClip subassets, if specified
            m_generatedClips = generateAnimationClips ?
                               CreateAnimationClips(settings, aseInfo, sprites) :
                               new GeneratedClip[0];

            m_clipCount = m_generatedClips.Length;

            // Add all subassets to the import context
            context.AddObjectToAsset(m_atlas.name, m_atlas);

            foreach (var sprite in sprites)
            {
                context.AddObjectToAsset(sprite.name, sprite);
            }

            foreach (var clipData in m_generatedClips)
            {
                if (clipData.createMode != GeneratedClip.CreateMode.Merge)
                {
                    context.AddObjectToAsset(clipData.name, clipData.clip);
                }
            }
        }
Exemple #3
0
        private GeneratedClip[] CreateAnimationClips(Settings settings, AsepriteFileInfo aseInfo, List <Sprite> sprites)
        {
            SpriteSheetData sheetData = aseInfo.spriteSheetData;

            var clipInfoLookup = new Dictionary <string, List <(Sprite sprite, int duration)> >();

            foreach (SpriteSheetData.FrameTag frameTag in sheetData.meta.frameTags)
            {
                var framesInfo = new List <(Sprite sprite, int duration)>();

                for (int i = frameTag.from; i <= frameTag.to; i++)
                {
                    SpriteSheetData.Frame frame = sheetData.frames[i];
                    Sprite sprite = sprites.Find((s) => { return(frame.filename.Equals(s.name)); });

                    if (ReferenceEquals(sprite, null))
                    {
                        continue;
                    }

                    int duration = frame.duration;
                    framesInfo.Add((sprite, duration));
                }

                string clipName = $"aseprite_{aseInfo.title}_{frameTag.name}";
                clipInfoLookup.Add(clipName, framesInfo);
            }

            var clips = new List <AnimationClip>(clipInfoLookup.Count);

            foreach (var kvp in clipInfoLookup)
            {
                string clipName = kvp.Key;
                List <(Sprite sprite, int duration)> clipInfo = kvp.Value;

                AnimationClip clip = new AnimationClip();
                clip.wrapMode = WrapMode.Loop;
                clip.name     = clipName;

                int[] frameTimesInMilliseconds = new int[clipInfo.Count];
                for (int iFrame = 0; iFrame < frameTimesInMilliseconds.Length; iFrame++)
                {
                    frameTimesInMilliseconds[iFrame] = clipInfo[iFrame].duration;
                }
                clip.frameRate = ClipSettings.CalculateAutoFrameRate(settings.MaxSampleRate, frameTimesInMilliseconds);

                AnimationClipSettings currentClipSettings = AnimationUtility.GetAnimationClipSettings(clip);
                currentClipSettings.loopTime = true;
                AnimationUtility.SetAnimationClipSettings(clip, currentClipSettings);

                var spriteBinding = new EditorCurveBinding();
                spriteBinding.type         = typeof(SpriteRenderer);
                spriteBinding.path         = clipSettings.spriteRendererPath;
                spriteBinding.propertyName = "m_Sprite";

                int clipLength = clipInfo.Count;
                var keyframes  = new List <ObjectReferenceKeyframe>(clipLength + 1);

                float currentDuration = 0f;

                for (int i = 0; i < clipLength; i++)
                {
                    var keyframe = new ObjectReferenceKeyframe();

                    keyframe.value = clipInfo[i].sprite;
                    keyframe.time  = currentDuration;
                    keyframes.Add(keyframe);

                    // Divide frame duration by 1000 because it is specified by Aseprite in milliseconds.
                    float keyDuration = clipInfo[i].duration / 1000f;
                    currentDuration += keyDuration;

                    // TODO: Miscreant: Do these calculations before any sec/msec conversions for more precision
                    // Tack on a duplicate of the last keyframe to ensure the last frame gets its full duration
                    if (i == clipLength - 1 && keyDuration > (1.0f / clip.frameRate))
                    {
                        keyframe = new ObjectReferenceKeyframe();
                        // The last frame will persist for one full sample, so subtract that from the current time
                        keyframe.time  = currentDuration - (1.0f / clip.frameRate);
                        keyframe.value = clipInfo[i].sprite;
                        keyframes.Add(keyframe);
                    }
                }

                AnimationUtility.SetObjectReferenceCurve(
                    clip,
                    spriteBinding,
                    keyframes.ToArray()
                    );

                clips.Add(clip);
            }

            return(FinalizeAnimationClips(aseInfo, clips));
        }