示例#1
0
    public void GenerateAnimations()
    {
        animationClips = new AnimationClip[sortedFrames.Length / 3];

        int animationCount = 0;
        for (int i=0; i<animationClips.Length; i++) {
            if (animationNames[i] != "") {
                AnimationClip animationClip;
                if (isOneFrame[i]) {
                    animationClip = GenerateAnimation(animationNames[i], frameRate, i * 3 + 1, 1); // use 2nd sprite
                } else {
                    animationClip = GenerateAnimation(animationNames[i], frameRate, i * 3, 4);

                    SerializedObject serializedClip = new SerializedObject(animationClip);
                    AnimationClipSettings clipSettings = new AnimationClipSettings(serializedClip.FindProperty("m_AnimationClipSettings"));

                    clipSettings.loopTime = true;

                    serializedClip.ApplyModifiedProperties();
                }

                animationClips[animationCount] = animationClip;
                animationCount++;
            }
        }
    }
    AnimationClip createAnimationClip(params Sprite[] sprites)
    {
        AnimationClip clip = new AnimationClip { frameRate = 9 };
        AnimationClipSettings setting = new AnimationClipSettings { loopTime = true };
        AnimationUtility.SetAnimationClipSettings(clip, setting);
        ObjectReferenceKeyframe[] keyframes = new ObjectReferenceKeyframe[sprites.Length];
        for (int i = 0; i < keyframes.Length; i++) {
            keyframes[i] = new ObjectReferenceKeyframe {
                value = sprites[i],
                time = i / clip.frameRate
            };
        }

        EditorCurveBinding curvebinding = EditorCurveBinding.PPtrCurve("", typeof(SpriteRenderer), "m_Sprite");
        AnimationUtility.SetObjectReferenceCurve(clip, curvebinding, keyframes);
        return clip;
    }
    static AnimationClip BuildAnimationClip(DirectoryInfo dictorys)
    {
        string animationName = dictorys.Name;
        //查找所有图片,因为我找的测试动画是.jpg
        FileInfo []images  = dictorys.GetFiles("*.jpg");
        AnimationClip clip = new AnimationClip();
        AnimationUtility.SetAnimationType(clip,ModelImporterAnimationType.Generic);
        EditorCurveBinding curveBinding = new EditorCurveBinding();
        curveBinding.type = typeof(SpriteRenderer);
        curveBinding.path="";
        curveBinding.propertyName = "m_Sprite";
        ObjectReferenceKeyframe[] keyFrames = new ObjectReferenceKeyframe[images.Length];
        //动画长度是按秒为单位,1/10就表示1秒切10张图片,根据项目的情况可以自己调节
        float frameTime = 1/10f;
        for(int i =0; i< images.Length; i++){
            Sprite sprite = Resources.LoadAssetAtPath<Sprite>(DataPathToAssetPath(images[i].FullName));
            keyFrames[i] =   new ObjectReferenceKeyframe ();
            keyFrames[i].time = frameTime *i;
            keyFrames[i].value = sprite;
        }
        //动画帧率,30比较合适
        clip.frameRate = 30;

        //有些动画我希望天生它就动画循环
        if(animationName.IndexOf("idle") >=0 )
        {
            //设置idle文件为循环动画
            SerializedObject serializedClip = new SerializedObject(clip);
            AnimationClipSettings clipSettings = new AnimationClipSettings(serializedClip.FindProperty("m_AnimationClipSettings"));
            clipSettings.loopTime = true;
            serializedClip.ApplyModifiedProperties();
        }
        string parentName = System.IO.Directory.GetParent(dictorys.FullName).Name;
        System.IO.Directory.CreateDirectory(AnimationPath +"/"+parentName);
        AnimationUtility.SetObjectReferenceCurve(clip,curveBinding,keyFrames);
        AssetDatabase.CreateAsset(clip,AnimationPath +"/"+parentName +"/" +animationName+".anim");
        AssetDatabase.SaveAssets();
        return clip;
    }
示例#4
0
    void CreateClip()
    {
        var obj = Selection.GetFiltered <Object>(SelectionMode.TopLevel);

        obj = Sort(obj);

        var time = 1 / frameRate * frameTime;

        ObjectReferenceKeyframe[] keyFrames = new ObjectReferenceKeyframe[obj.Length + 1];
        for (int i = 0; i <= obj.Length; i++)
        {
            Sprite sprite = AssetDatabase.LoadAssetAtPath <Sprite>(AssetDatabase.GetAssetPath(obj[i == obj.Length ? 0 : i]));
            keyFrames[i]       = new ObjectReferenceKeyframe();
            keyFrames[i].time  = time * i;
            keyFrames[i].value = sprite;
        }

        AnimationClip clip = new AnimationClip();

        clip.frameRate = frameRate;

        AnimationClipSettings clipSettings = AnimationUtility.GetAnimationClipSettings(clip);

        clipSettings.loopTime = true;
        AnimationUtility.SetAnimationClipSettings(clip, clipSettings);

        EditorCurveBinding curveBinding = new EditorCurveBinding();

        curveBinding.type         = typeof(SpriteRenderer);
        curveBinding.propertyName = "m_Sprite";
        AnimationUtility.SetObjectReferenceCurve(clip, curveBinding, keyFrames);

        if (!Directory.Exists("Assets/" + folder))
        {
            Directory.CreateDirectory("Assets/" + folder);
        }

        AssetDatabase.CreateAsset(clip, "Assets/" + folder + "/" + fileName + ".anim");
    }
示例#5
0
    static AnimationClip BuildAnimationClip(DirectoryInfo dictorys, string name)
    {
        string animationName = dictorys.Name;

        //查找所有图片,因为我找的测试动画是.jpg
        FileInfo[]    images = dictorys.GetFiles().ToList().Where(x => (x.Extension.ToLower() == ".png" || x.Extension.ToLower() == ".tga")).OrderBy(x => (TurnNumToInt(x.Name))).ToArray();
        AnimationClip clip   = new AnimationClip();

        EditorCurveBinding curveBinding = new EditorCurveBinding();

        curveBinding.type         = typeof(SpriteRenderer);
        curveBinding.path         = "";
        curveBinding.propertyName = "m_Sprite";
        ObjectReferenceKeyframe[] keyFrames = new ObjectReferenceKeyframe[images.Length];
        //动画长度是按秒为单位,1/10就表示1秒切10张图片,根据项目的情况可以自己调节
        float frameTime = 1f / 12f;

        for (int i = 0; i < images.Length; i++)
        {
            Sprite sprite = AssetDatabase.LoadAssetAtPath <Sprite>(DataPathToAssetPath(images[i].FullName).Replace("\\", "/"));

            keyFrames[i]       = new ObjectReferenceKeyframe();
            keyFrames[i].time  = frameTime * Mathf.Max(0, (i + 1 - Mathf.Pow(1.07f, i)));
            keyFrames[i].value = sprite;
        }
        //动画帧率,30比较合适
        clip.frameRate = 30;

        SerializedObject      serializedClip = new SerializedObject(clip);
        AnimationClipSettings clipSettings   = new AnimationClipSettings(serializedClip.FindProperty("m_AnimationClipSettings"));

        clipSettings.loopTime = true;
        serializedClip.ApplyModifiedProperties();

        AnimationUtility.SetObjectReferenceCurve(clip, curveBinding, keyFrames);

        return(clip);
    }
示例#6
0
        // Start baking an animation state, clip or timeline, also called for each next clip in the baking array
        public void BakeClip()
        {
#if UNITY_EDITOR
            if (mode == Mode.AnimationClips && inheritClipSettings)
            {
                AnimationClipSettings originalSettings = AnimationUtility.GetAnimationClipSettings(animationClips[currentClipIndex]);
                addLoopFrame = originalSettings.loopTime;
            }
            else
            {
                if (mode == Mode.Realtime)
                {
                    addLoopFrame = clipSettings.loopTime && clipSettings.loopBlend;
                }
                else
                {
                    addLoopFrame = clipSettings.loopTime;
                }
            }

            StartBaking();
#endif
        }
示例#7
0
    //将图集生成动画文件
    private static AnimationClip BuildAnimationClip(DirectoryInfo dictoryAnimations)
    {
        string animationName = dictoryAnimations.Name;
        FileInfo[] images = dictoryAnimations.GetFiles("*." + imageFormat);
        AnimationClip clip = new AnimationClip();
        AnimationUtility.SetAnimationType(clip, ModelImporterAnimationType.Generic); //设置动画类型
        EditorCurveBinding curveBinding = new EditorCurveBinding();
        curveBinding.type = typeof (SpriteRenderer);
        curveBinding.path = "";
        curveBinding.propertyName = "m_Sprite";
        ObjectReferenceKeyframe[] keyFrames = new ObjectReferenceKeyframe[images.Length];

        for (int i = 0; i < images.Length; i++)
        {
            Sprite sprite = Resources.LoadAssetAtPath<Sprite>(DataPathToAssetPath(images[i].FullName));
            keyFrames[i] = new ObjectReferenceKeyframe();
            keyFrames[i].time = frameTime*i;
            keyFrames[i].value = sprite;
        }
        clip.frameRate = frameRate;
        if (animationName.IndexOf("idle") >= 0)
        {
            //设置idle动画为循环动画
            SerializedObject serializedClip = new SerializedObject(clip);
            AnimationClipSettings clipSettings =
                new AnimationClipSettings(serializedClip.FindProperty("m_AnimationClipSettings"));
            clipSettings.loopTime = true;
            serializedClip.ApplyModifiedProperties();
        }

        string parentName = System.IO.Directory.GetParent((dictoryAnimations.FullName)).Name;
        System.IO.Directory.CreateDirectory(animationPath + "/" + parentName);
        AnimationUtility.SetObjectReferenceCurve(clip, curveBinding, keyFrames);
        AssetDatabase.CreateAsset(clip, animationPath + "/" + parentName + "/" + animationName + ".anim");
        AssetDatabase.SaveAssets();
        return clip;
    }
示例#8
0
        private void UpdateClipSettings(AnimationClip clip, bool isNewClip)
        {
            clip.wrapMode = WrapMode.Loop;

            AnimationUtility.SetAnimationType(clip, ModelImporterAnimationType.Generic);

            AnimationClipSettings settings = AnimationUtility.GetAnimationClipSettings(clip);

            settings.loopTime  = true;
            settings.startTime = 0f;
            // If animation is a single keyframe then make sure stop time is a small value rather than 0,
            // as Unity will otherwise default to an animation length of 1 second
            settings.stopTime = Mathf.Max(clip.length, 0.01f);

            SpineUtilities.SetAnimationSettings(clip, settings);

            // Add animation clip to layer 0 of the animator controller
            UnityEditorInternal.AnimatorController controller = transform.GetComponent <Animator>().runtimeAnimatorController as UnityEditorInternal.AnimatorController;

            if (controller && isNewClip)
            {
                UnityEditorInternal.AnimatorController.AddAnimationClipToController(controller, clip);
            }
        }
示例#9
0
    private static void CheckSingleNode(string path)
    {
        string lowerPath = path.ToLower();

        if (lowerPath.IndexOf("idle") < 0 && lowerPath.IndexOf("run") < 0 && lowerPath.IndexOf("sleep") < 0 && lowerPath.IndexOf("coma") < 0)
        {
            return;
        }
        path = path.Replace('\\', '/');
        AnimationClip controller = AssetDatabase.LoadAssetAtPath <AnimationClip>(path);

        if (null == controller)
        {
            return;
        }
        AnimationClipSettings clipsetting = AnimationUtility.GetAnimationClipSettings(controller);

        if (!clipsetting.loopTime)
        {
            Debug.Log(string.Concat("Message:", path, "-->:", "修改设置"));
        }
        clipsetting.loopTime = true;
        AnimationUtility.SetAnimationClipSettings(controller, clipsetting);
    }
示例#10
0
    public void SetUpTrackProperties(AnimatedObject aObj, Vector3 trackPosition, Timeline t, int i, Material unselectedCol, Material selectedCol)
    {
        animatedObject = aObj;
        timeline       = t;
        aObj.beizerPathGroup.beizerPathData.animTrack = this;

        transform.parent        = timeline.transform;
        transform.localPosition = trackPosition;

        clip          = new AnimationClip();
        clip.name     = $"FunClip {i}";
        clip.wrapMode = WrapMode.Loop;
        Debug.Log("wrapMode " + clip.wrapMode);

        unselectedColor = unselectedCol;
        selectedColor   = selectedCol;

        AnimationClipSettings tSettings = AnimationUtility.GetAnimationClipSettings(clip);

        Debug.Log(tSettings.loopTime);
        tSettings.loopTime = true;
        Debug.Log(tSettings.loopTime);

        AnimationUtility.SetAnimationClipSettings(clip, tSettings);


        AssetDatabase.CreateAsset(clip, $"Assets/clip_{i}.anim");
        animCurve           = ScriptableObject.CreateInstance <AnimCurve>();
        animCurve.clip      = clip;
        animCurve.animTrack = this;
        animCurve.SetupAnimationCurves();
        timeline.trackSectionData.ConnectTracksToPlayableGraph(clip, animatedObject.GetComponent <Animator>());
        SubscribeToAnimationEvents();

        Debug.Log(animCurve);
    }
 public AnimationClipInfoProperties(AnimationClip animationClip, AnimationClipSettings animationClipSettings)
 {
     this.animationClip         = animationClip;
     this.animationClipSettings = animationClipSettings;
 }
示例#12
0
    private void CreateCharacter()
    {
        var obj      = new GameObject("Character");
        var animator = obj.AddComponent <Animator>();
        var renderer = obj.AddComponent <SpriteRenderer>();

        // ぼやけを除去
        this.m_Image.filterMode = FilterMode.Point;

        // 15フレームに一回アニメーションする
        float frameLength = 15f / 60f;
        // 画像は横にアニメーションする
        int frameCount = this.m_Image.width / this.m_CropWidth;
        // 画像は縦に種類が並んでいる
        int  stateCount           = this.m_Image.height / this.m_CropHeight;
        bool extendedCharaChipSet = false;

        // ただし、8方向のチップセットが存在するので、それに対処する
        if (frameCount == 6 || frameCount == 10)
        {
            frameCount         >>= 1;
            stateCount         <<= 1;
            extendedCharaChipSet = true;
        }

        // スプライト配列の作成
        Sprite[,] sprites = new Sprite[stateCount, frameCount];

        // Blend Tree 設定用のVector2配列の準備
        Vector2[] positions =
        {
            new Vector2(0,   1),
            new Vector2(1,   0),
            new Vector2(-1,  0),
            new Vector2(0,  -1),
            new Vector2(1,   1),
            new Vector2(-1,  1),
            new Vector2(1,  -1),
            new Vector2(-1, -1),
        };

        // スプライトの切り出し
        Texture2D[,] textures = new Texture2D[stateCount, frameCount];
        for (int y = 0; y < stateCount; y++)
        {
            for (int x = 0; x < frameCount; x++)
            {
                //指定された幅高さでテスクチャからスプライトを切り出す
                var rect    = new Rect(x * this.m_CropWidth, y * this.m_CropHeight, this.m_CropWidth, this.m_CropHeight);
                var texture = new Texture2D(m_CropWidth, m_CropHeight);
                var colors  = m_Image.GetPixels((int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height);
                texture.SetPixels(colors);
                var bin = texture.EncodeToPNG();
                File.WriteAllBytes(m_Folder + $"{m_Image.name + "_" + y + x}.png", bin);
                AssetDatabase.Refresh();
                //var sprite = Sprite.Create(this.m_Image, rect, new Vector2(0.5f, 0.5f), this.m_CropHeight);

                /*var sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f), m_CropHeight);
                 * sprite.name = this.m_Image.name + "_" + y + x;
                 * sprite.texture.filterMode = FilterMode.Point;
                 * sprites[y, x] = sprite;*/
                //AssetDatabase.CreateAsset(texture, m_Folder + $"{sprite.name}.png");
            }
        }
        for (int y = 0; y < stateCount; y++)
        {
            for (int x = 0; x < frameCount; x++)
            {
                var texture = AssetDatabase.LoadAssetAtPath <Texture2D>(m_Folder + $"{m_Image.name + "_" + y + x}.png");
                var sprite  = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f), m_CropHeight);
                sprite.name = this.m_Image.name + "_" + y + x;
                sprite.texture.filterMode = FilterMode.Point;
                sprites[y, x]             = sprite;
            }
        }
        // アニメータコントローラの作成
        AnimatorController animatorController = AnimatorController.CreateAnimatorControllerAtPath(m_Folder + m_FileName);

        // 名前はテクスチャ名にする
        animatorController.name = this.m_Image.name;
        //向きと状態指定用のパラメータを追加
        animatorController.AddParameter("DirectionX", AnimatorControllerParameterType.Float);
        animatorController.AddParameter("DirectionY", AnimatorControllerParameterType.Float);
        animatorController.AddParameter("Walking", AnimatorControllerParameterType.Bool);

        // アニメータコントローラにベースレイヤを追加
        //animatorController.AddLayer("Base");

        // 止まり状態を追加する
        BlendTree     waitBlendTree;
        AnimatorState waitState = animatorController.CreateBlendTreeInController("Wait", out waitBlendTree);

        waitBlendTree.name = "Blend Tree";

        // 止まり状態はアニメーションしないが
        // 方向によってスプライトが変化する
        waitBlendTree.blendType       = BlendTreeType.SimpleDirectional2D;
        waitBlendTree.blendParameter  = "DirectionX";
        waitBlendTree.blendParameterY = "DirectionY";

        // 状態の数だけループ
        for (int i = 0; i < stateCount; i++)
        {
            // アニメーションしないので、キーフレームを1つだけ用意する
            ObjectReferenceKeyframe[] keyFrames = new ObjectReferenceKeyframe[1];
            keyFrames[0] = new ObjectReferenceKeyframe
            {
                time  = 0.0f,// 止まりのスプライトを指定
                value = sprites[i, 1]
            };
            // アニメーションクリップの作成
            AnimationClip clip = new AnimationClip
            {
                // 名前は歩きとかぶるので、wait_状態のインデックスにする
                name = "Wait_" + i,
                // はみ出た部分は消す
                wrapMode = WrapMode.Clamp
            };
            // カーブの作成
            EditorCurveBinding curveBinding = new EditorCurveBinding
            {
                //ファイルは存在しない
                path = string.Empty,
                //スプライトをアニメーションするのでtypeにSpriteRenderer
                // propertyNameにはm_Spriteを指定
                type         = typeof(SpriteRenderer),
                propertyName = "m_Sprite"
            };
            //クリップとカーブにキーフレームをバインド
            AnimationUtility.SetObjectReferenceCurve(clip, curveBinding, keyFrames);
            //状態を止まり状態のブレンドツリーに追加
            waitBlendTree.AddChild(clip, positions[i]);
            // AnimationClipをAssetとして保存
            AssetDatabase.CreateAsset(clip, m_Folder + $"{Path.GetFileNameWithoutExtension(m_FileName)}_{clip.name}.anim");
        }

        // 歩き状態を追加する
        BlendTree     walkBlendTree;
        AnimatorState walkState = animatorController.CreateBlendTreeInController("Walk", out walkBlendTree);

        walkBlendTree.name = "Blend Tree";

        // 歩き状態は歩く方向によってアニメーションが変化する
        walkBlendTree.blendType       = BlendTreeType.SimpleDirectional2D;
        walkBlendTree.blendParameter  = "DirectionX";
        walkBlendTree.blendParameterY = "DirectionY";

        // 状態の数だけループ
        for (int y = 0; y < stateCount; y++)
        {
            //キーフレーム配列を作成
            // 右足、止まり、左足、止まり、右足とアニメーションする
            // ループするので、最後に右足を入れないと左足の後の止まりが短く不自然になる
            ObjectReferenceKeyframe[] keyFrames = new ObjectReferenceKeyframe[frameCount + 2];
            // 8方向拡張対応
            int offsetX = 0, offsetY = 0;
            if (extendedCharaChipSet && y >= (stateCount >> 1))
            {
                offsetX = frameCount;
                offsetY = -(stateCount >> 1);
            }
            // 普通のアニメーションの作成
            for (int x = 0; x < frameCount; x++)
            {
                // キーフレームの追加
                keyFrames[x] = new ObjectReferenceKeyframe {
                    time = x * frameLength, value = sprites[y, x]
                };
            }
            // 2枚目->1枚目とアニメーションする
            for (int x = 1; x >= 0; x--)
            {
                int index = frameCount + 1 - x;
                keyFrames[index] = new ObjectReferenceKeyframe {
                    time = index * frameLength, value = sprites[y, x]
                };
            }

            // アニメーションクリップの作成
            AnimationClip clip = new AnimationClip
            {
                // 名前は状態のインデックスにする
                name = $"Walk_{y.ToString()}",
                // はみ出た部分は消す
                wrapMode = WrapMode.Clamp
            };
            // カーブの作成
            EditorCurveBinding curveBinding = new EditorCurveBinding
            {
                // ファイルは存在しない
                path = string.Empty,
                // スプライトをアニメーションするのでtypeにSpriteRenderer
                // propertyNameにはm_Spriteを指定
                type         = typeof(SpriteRenderer),
                propertyName = "m_Sprite"
            };
            // クリップとカーブにキーフレームをバインド
            AnimationUtility.SetObjectReferenceCurve(clip, curveBinding, keyFrames);
            // LoopTimeが直接設定出来ないので一旦シリアライズする
            SerializedObject serializedClip = new SerializedObject(clip);
            // アニメーションクリップ設定の取り出し
            AnimationClipSettings animationClipSettings = new AnimationClipSettings(serializedClip.FindProperty("m_AnimationClipSettings"))
            {
                // LoopTimeを有効にする
                LoopTime = true
            };
            // 設定を書き戻す
            serializedClip.ApplyModifiedProperties();
            // 状態を歩き状態のブレンドツリーに追加
            walkBlendTree.AddChild(clip, positions[y]);
            // AnimationClipをAssetとして保存
            AssetDatabase.CreateAsset(clip, m_Folder + $"{Path.GetFileNameWithoutExtension(m_FileName)}_{clip.name}.anim");
        }

        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();

        // 止まり->歩きのトランジションを作成
        AnimatorStateTransition waitToWalk = waitState.AddTransition(walkState);

        // Walkingフラグがtrueの時
        waitToWalk.AddCondition(AnimatorConditionMode.If, 0, "Walking");

        // 歩き->止まりのトランジションを作成
        AnimatorStateTransition walkToWait = walkState.AddTransition(waitState);

        // Walkingフラグがfalseの時
        walkToWait.AddCondition(AnimatorConditionMode.IfNot, 0, "Walking");

        // アニメータコントローラに設定
        animator.runtimeAnimatorController = (animatorController as RuntimeAnimatorController);

        // とりあえず0,0のスプライトをデフォルトにセット
        renderer.sprite = sprites[0, 0];
    }
示例#13
0
    //生成动画
    AseAnimationSettings GenerateAnimation(AssetImportContext ctx, string name, AseFrame[] frames, int startFrame = 0, int endFrame = 0)
    {
        AseAnimationSettings animationSetting = GetAnimationSetting(name);

        if (generateAnimation)
        {
            AnimationClip clip = new AnimationClip();
            clip.name      = name;
            clip.frameRate = 25;

            if (endFrame == 0)
            {
                endFrame = frames.Length - 1;
            }

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

            int length = endFrame - startFrame + 1;
            ObjectReferenceKeyframe[] spriteKeyFrames = new ObjectReferenceKeyframe[length + 1];

            float time = 0;
            for (int i = startFrame; i <= endFrame; i++)
            {
                ObjectReferenceKeyframe frame = new ObjectReferenceKeyframe();
                frame.time  = time;
                frame.value = frames[i].sprite;
                time       += frames[i].duration;

                spriteKeyFrames[i - startFrame] = frame;
            }

            //单独设置最后一帧
            float frameTime = 1f / clip.frameRate;
            ObjectReferenceKeyframe lastFrame = new ObjectReferenceKeyframe();
            lastFrame.time  = time - frameTime;
            lastFrame.value = frames[endFrame].sprite;
            spriteKeyFrames[spriteKeyFrames.Length - 1] = lastFrame;

            AnimationUtility.SetObjectReferenceCurve(clip, spriteBinding, spriteKeyFrames);
            AnimationClipSettings settings = AnimationUtility.GetAnimationClipSettings(clip);

            //循环设置
            if (animationSetting.loop)
            {
                settings.loopTime = true;
                clip.wrapMode     = WrapMode.Loop;
            }
            else
            {
                settings.loopTime = false;
                clip.wrapMode     = WrapMode.Once;
            }

            AnimationUtility.SetAnimationClipSettings(clip, settings);
            ctx.AddObjectToAsset(name, clip);

            //string filePath = string.Format("{0}/{1}.anim", GetFileDic(ctx.assetPath), name);
            //AssetDatabase.CreateAsset(clip, filePath);
            //clip = AssetDatabase.LoadAssetAtPath(filePath, typeof(AnimationClip)) as AnimationClip;
            //Debug.Log(AssetDatabase.CopyAsset();
            //AssetDatabase.CopyAsset(AssetDatabase.GetAssetPath(clip), filePath);
        }

        return(animationSetting);
    }
    static AnimationClip BuildAnimationClip(Sprite[] images, string name)
    {
        //获取的是 单个动作的名称
        string animationName = name;
        //查找所有图片

        AnimationClip clip = new AnimationClip();

        AnimationUtility.SetAnimationType(clip, ModelImporterAnimationType.Generic);
        EditorCurveBinding curveBinding = new EditorCurveBinding();

        curveBinding.type         = typeof(SpriteRenderer);
        curveBinding.path         = "";
        curveBinding.propertyName = "m_Sprite";

        ObjectReferenceKeyframe[] keyFrames = new ObjectReferenceKeyframe[images.Length];

        //动画长度是按秒为单位,1/10就表示1秒切10张图片
        float frameTime = 1 / 10f;

        for (int i = 0; i < images.Length; i++)
        {
            //根据名字 读取到sprite
            Sprite sprite = images[i];
            // sprite.pixelsPerUnit
            keyFrames[i]       = new ObjectReferenceKeyframe();
            keyFrames[i].time  = frameTime * i;
            keyFrames[i].value = sprite;
        }

        if (keyFrames.Length == 1)
        {
            keyFrames = new ObjectReferenceKeyframe[5];
            Sprite sprite = images[0];
            for (int i = 0; i < 5; i++)
            {
                keyFrames[i]       = new ObjectReferenceKeyframe();
                keyFrames[i].time  = frameTime * i;
                keyFrames[i].value = sprite;
            }
        }

        //动画帧率,30比较合适
        clip.frameRate = 30;


        //动画名字里包含Idle的一般设置为循环
        if (animationName.ToLower().IndexOf("idle", StringComparison.Ordinal) >= 0)
        {
            //设置idle文件为循环动画
            SerializedObject      serializedClip = new SerializedObject(clip);
            AnimationClipSettings clipSettings   =
                new AnimationClipSettings(serializedClip.FindProperty("m_AnimationClipSettings"))
            {
                loopTime = true
            };
            serializedClip.ApplyModifiedProperties();
        }

        string parentName = name;

        Directory.CreateDirectory(AnimationPath + "/" + parentName);
        AnimationUtility.SetObjectReferenceCurve(clip, curveBinding, keyFrames);
        AssetDatabase.CreateAsset(clip, AnimationPath + "/" + parentName + "/" + animationName + ".anim");
        AssetDatabase.SaveAssets();
        return(clip);
    }
 /// <summary>
 /// Clip生成実体
 /// </summary>
 /// <param name="sprites">各フレームに割り当てるSpriteの配列</param>
 AnimationClip CreateAnimationClip(params Sprite[] sprites)
 {
     /// Copyright (c) 2015 kyusyukeigo
     /// Released under the MIT license
     /// https://github.com/anchan828/unite2015tokyo/blob/master/LICENSE
     
     var animationClip = new AnimationClip { frameRate = 12 };
     var animationClipSettings = new AnimationClipSettings { loopTime = true };
     AnimationUtility.SetAnimationClipSettings(animationClip, animationClipSettings);
     var objectReferenceKeyframes = new ObjectReferenceKeyframe[sprites.Length];
     for (var i = 0; i < objectReferenceKeyframes.Length; i++)
     {
         objectReferenceKeyframes[i] = new ObjectReferenceKeyframe
         {
             value = sprites[i],
             time = i / animationClip.frameRate
         };
     }
     var editorCurveBinding = EditorCurveBinding.PPtrCurve("", typeof(SpriteRenderer), "m_Sprite");
     AnimationUtility.SetObjectReferenceCurve(animationClip, editorCurveBinding, objectReferenceKeyframes);
     return animationClip;
 }
示例#16
0
    void OnGUI()
    {
        EditorGUILayout.LabelField("一个角色的切好的Sprite(任选一个)");
        spritesheet = EditorGUILayout.ObjectField(spritesheet, typeof(Sprite), false) as Sprite;
        EditorGUILayout.LabelField("每个Walk动画的帧数");
        iFramesPerLoop = EditorGUILayout.IntField(iFramesPerLoop);
        EditorGUILayout.LabelField("Sprite中总共动画个数");
        iTotalLoops = EditorGUILayout.IntField(iTotalLoops);
        bMirrorLR234 = EditorGUILayout.ToggleLeft("第2,3,4个动画生成左右对称的两个动画", bMirrorLR234);
        bIdleForLoop = EditorGUILayout.ToggleLeft("给每个动画创建一个Idle动画", bIdleForLoop);
        EditorGUILayout.LabelField("Idle动画单帧位于每个动画中的位置(从1开始)");
        iIdleFrameForLoop = EditorGUILayout.IntField(iIdleFrameForLoop);
        EditorGUILayout.LabelField("每秒帧数(Samples)");
        iSamples = EditorGUILayout.IntField(iSamples);

        if (GUILayout.Button("载入生成"))
        {
            string sheetPath = AssetDatabase.GetAssetPath(spritesheet);
            //Assets/Resources/Sprites/Character/chara_01.png
            characterName = Path.GetFileNameWithoutExtension(sheetPath);
            //chara_01
            directory = Path.GetDirectoryName(sheetPath);
            //Assets/Resources/Sprites/Character/

            sprites = AssetDatabase.LoadAllAssetsAtPath(sheetPath).OfType<Sprite>().ToArray();

            if (!bMirrorLR234)
            {
                //原本的代码
                for (int i = 0; i < iTotalLoops; i++)
                {
                    AnimationClip clip = new AnimationClip();
                    clip.frameRate = iFramesPerLoop;

                    EditorCurveBinding curveBinding = new EditorCurveBinding();
                    curveBinding.path = "";
                    curveBinding.propertyName = "m_Sprite";
                    curveBinding.type = typeof(SpriteRenderer);

                    ObjectReferenceKeyframe[] keys = new ObjectReferenceKeyframe[iFramesPerLoop];
                    for (int j = 0; j < iFramesPerLoop; j++)
                    {
                        keys[j] = new ObjectReferenceKeyframe();
                        keys[j].time = (1.0f / iFramesPerLoop) * j;
                        keys[j].value = sprites[iFramesPerLoop * i + j];
                    }

                    AnimationUtility.SetObjectReferenceCurve(clip, curveBinding, keys);
                    AssetDatabase.CreateAsset(clip, directory + "/" + characterName + "_" + clipNames[i] + ".anim");
                }
            }
            else
            {
                //234要生成镜像的代码
                for (int i = 0; i < iTotalLoops + 3; i++)
                {
                    int targetKey;
                    targetKey = (i + 1) / 2;
                    //0 1 2 3 4 5 6 7
                    //covert to
                    //0 1 1 2 2 3 3 4

                    AnimationClip clip = new AnimationClip();
                    clip.frameRate = iSamples;

                    EditorCurveBinding curveBinding = new EditorCurveBinding();
                    curveBinding.path = "";
                    curveBinding.propertyName = "m_Sprite";
                    curveBinding.type = typeof(SpriteRenderer);

                    ObjectReferenceKeyframe[] keys = new ObjectReferenceKeyframe[iFramesPerLoop + 1];
                    for (int j = 0; j < iFramesPerLoop; j++)
                    {
                        keys[j] = new ObjectReferenceKeyframe();
                        keys[j].time = (1.0f / iSamples) * j;
                        keys[j].value = sprites[iFramesPerLoop * targetKey + j];
                    }
                    keys[3] = new ObjectReferenceKeyframe();
                    keys[3].time = (1.0f / iSamples) * 3;
                    keys[3].value = sprites[iFramesPerLoop * targetKey + 1];

                    switch (i)
                    {
                        case 2:
                        case 4:
                        case 6:
                            EditorCurveBinding cb2 = new EditorCurveBinding();
                            cb2.path = "";
                            cb2.propertyName = "m_FlipX";
                            cb2.type = typeof(SpriteRenderer);
                            AnimationCurve ac = new AnimationCurve();
                            ac.AddKey(0f, 1f);
                            AnimationUtility.SetEditorCurve(clip, cb2, ac);
                            Debug.Log(i);
                            break;
                    }


                    AnimationUtility.SetObjectReferenceCurve(clip, curveBinding, keys);
                    AssetDatabase.CreateAsset(clip, directory + "/" + characterName + "_" + clipNames[i] + ".anim");
                }
                if (bIdleForLoop)
                {
                    for (int i = 0; i < iTotalLoops + 3; i++)
                    {
                        int targetKey;
                        targetKey = (i + 1) / 2;
                        //0 1 2 3 4 5 6 7
                        //covert to
                        //0 1 1 2 2 3 3 4

                        AnimationClip clip = new AnimationClip();
                        clip.frameRate = iSamples;

                        EditorCurveBinding curveBinding = new EditorCurveBinding();
                        curveBinding.path = "";
                        curveBinding.propertyName = "m_Sprite";
                        curveBinding.type = typeof(SpriteRenderer);

                        ObjectReferenceKeyframe[] keys = new ObjectReferenceKeyframe[1];
                        keys[0] = new ObjectReferenceKeyframe();
                        keys[0].time = 0f;
                        keys[0].value = sprites[iFramesPerLoop * targetKey + 1];
                        switch (i)
                        {
                            case 2:
                            case 4:
                            case 6:
                                EditorCurveBinding cb2 = new EditorCurveBinding();
                                cb2.path = "";
                                cb2.propertyName = "m_FlipX";
                                cb2.type = typeof(SpriteRenderer);
                                AnimationCurve ac = new AnimationCurve();
                                ac.AddKey(0f, 1f);
                                AnimationUtility.SetEditorCurve(clip, cb2, ac);
                                Debug.Log(i);
                                break;
                        }

                        AnimationUtility.SetObjectReferenceCurve(clip, curveBinding, keys);
                        AssetDatabase.CreateAsset(clip, directory + "/" + characterName + "_" + clipNamesIdle[i] + "_Idle.anim");
                    }
                }
            }
            string[] folders = new string[1];
            folders[0] = directory;
            string[] clipPaths = AssetDatabase.FindAssets(characterName, folders);

            List<AnimationClip> clips = new List<AnimationClip>();
            for (int i = 0; i < clipPaths.Length; i++)
            {
                AnimationClip c = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(clipPaths[i]), typeof(AnimationClip)) as AnimationClip;
                if (c != null)
                    clips.Add(c);
            }

            for (int i = 0; i < clips.Count; i++)
            {
                SerializedObject serializedClip = new SerializedObject(clips[i]);
                AnimationClipSettings clipSettings = new AnimationClipSettings(serializedClip.FindProperty("m_AnimationClipSettings"));

                clipSettings.loopTime = true;

                serializedClip.ApplyModifiedProperties();
            }

            AnimatorController controller = AnimatorController.CreateAnimatorControllerAtPath(directory + "/" + characterName + "_AnimatorController.controller");
            controller.AddParameter("X", AnimatorControllerParameterType.Float);
			controller.AddParameter("Y", AnimatorControllerParameterType.Float);

			BlendTree tree;
            controller.CreateBlendTreeInController("Walk", out tree, 0);
			tree.blendType = BlendTreeType.SimpleDirectional2D;
            tree.blendParameter = "X";
			tree.blendParameterY = "Y";
            tree.useAutomaticThresholds = false;
			int cc = (bIdleForLoop ? clips.Count / 2 : clips.Count);
			for (int i = 0; i < cc; i++) 
            {
				double d = i * Mathf.PI * 2 / cc;
				float x, y;
				y = (float)System.Math.Cos(d);
				x = (float)System.Math.Sin(d);
				tree.AddChild(clips[i], new Vector2(x, y));
            }

            GameObject go = GameObject.Find(characterName);
            if (go == null)
            {
                go = new GameObject(characterName);
                go.AddComponent<SpriteRenderer>().sprite = sprites[0];
                go.AddComponent<Animator>().runtimeAnimatorController = controller;
            }
            else
            {
                SpriteRenderer sr = go.GetComponent<SpriteRenderer>();
                if (sr == null)
                    go.AddComponent<SpriteRenderer>().sprite = sprites[0];
                else
                    sr.sprite = sprites[0];

                Animator anim = go.GetComponent<Animator>();
                if (anim == null)
                    go.AddComponent<Animator>().runtimeAnimatorController = controller;
                else
                    anim.runtimeAnimatorController = controller;
            }

            PrefabUtility.CreatePrefab(directory + "/" + characterName + ".prefab", go);
        }

    }
示例#17
0
        public static void ReloadMecanimController(ActorBaseComponent actorComponent, UnityEditor.Animations.AnimatorController animatorController)
        {
            Nima.Actor actor = actorComponent.Asset.Actor;

            string path = AssetDatabase.GetAssetPath(animatorController);

            UnityEngine.Object[] assets = AssetDatabase.LoadAllAssetsAtPath(path);

            List <Nima.Animation.ActorAnimation> alreadyUsedAnimations = new List <Nima.Animation.ActorAnimation>();

            foreach (UnityEngine.Object asset in assets)
            {
                AnimationClip clip = asset as AnimationClip;
                if (clip == null)
                {
                    continue;
                }

                bool exists = false;
                foreach (Nima.Animation.ActorAnimation actorAnimation in actor.Animations)
                {
                    if (actorAnimation.Name == clip.name)
                    {
                        exists = true;
                        alreadyUsedAnimations.Add(actorAnimation);
                        clip.SetCurve("", typeof(GameObject), "null", AnimationCurve.Linear(0, 0, actorAnimation.Duration, 0));
                        AnimationClipSettings clipSettings = AnimationUtility.GetAnimationClipSettings(clip);
                        clipSettings.stopTime = actorAnimation.Duration;
                        clipSettings.loopTime = actorAnimation.IsLooping;
                        AnimationUtility.SetAnimationClipSettings(clip, clipSettings);

                        EditorUtility.SetDirty(clip);
                        break;
                    }
                }
                if (!exists)
                {
                    AnimationClip.DestroyImmediate(clip, true);
                }
            }

            foreach (Nima.Animation.ActorAnimation actorAnimation in actor.Animations)
            {
                int idx = alreadyUsedAnimations.IndexOf(actorAnimation);
                if (idx == -1)
                {
                    AnimationClip animationClip = new AnimationClip();
                    animationClip.name = actorAnimation.Name;
                    animationClip.SetCurve("", typeof(GameObject), "null", AnimationCurve.Linear(0, 0, actorAnimation.Duration, 0));
                    AnimationClipSettings clipSettings = AnimationUtility.GetAnimationClipSettings(animationClip);
                    clipSettings.stopTime = actorAnimation.Duration;
                    clipSettings.loopTime = actorAnimation.IsLooping;
                    AnimationUtility.SetAnimationClipSettings(animationClip, clipSettings);

                    AssetDatabase.AddObjectToAsset(animationClip, animatorController);

                    EditorUtility.SetDirty(animationClip);
                }
            }

            EditorUtility.SetDirty(animatorController);
            AssetDatabase.Refresh();
            AssetDatabase.SaveAssets();
        }
示例#18
0
        public string Process()
        {
            this.rawClip = animatorState.motion as AnimationClip;
            if (!rawClip)
            {
                return(null);
            }
            this.stateFlag = findStateFlag(animatorState);
            //查找标记,检查是否可以跳过
            if (stateFlag && stateFlag.skipCompressed)
            {
                return(null);
            }
            var size = UnityEngine.Profiler.GetRuntimeMemorySize(rawClip);

            //小于16K 不压缩
            if (size < 1024 * 16)
            {
                return(null);
            }

            string rawClipPath = AssetDatabase.GetAssetPath(rawClip);

            if (string.IsNullOrEmpty(rawClipPath))
            {
                return(null);
            }

            string anim_gen_dir = Path.GetDirectoryName(rawClipPath) + "/_anim_gen_";
            string dataDir      = anim_gen_dir + "/datas";
            string stubDir      = anim_gen_dir + "/stubs";

            Directory.CreateDirectory(anim_gen_dir);
            Directory.CreateDirectory(dataDir);
            Directory.CreateDirectory(stubDir);

            this.shareData = getShareData(anim_gen_dir);
            this.stubClip  = new AnimationClip();
            AnimationClipSettings settings = AnimationUtility.GetAnimationClipSettings(rawClip);

            stubClip.SetCurve("", typeof(CompressedAnimationDirver), "stubAnimParam", AnimationCurve.Linear(0, 0, rawClip.length, 1));
            stubClip.name = rawClip.name + "_stub";
            this.clipData = CompressClipData();
            AnimationUtility.SetAnimationClipSettings(stubClip, settings);

            //*注意:这里是为了兼容通过AnimationClipSettings设置Loop而Wrap没设置
            if (settings.loopTime)
            {
                clipData.wrapMode = (byte)WrapMode.Loop;
                stubClip.wrapMode = WrapMode.Loop;
            }
            else
            {
                stubClip.wrapMode = rawClip.wrapMode;
            }
            animatorState.motion = stubClip;
            AssetDatabase.CreateAsset(stubClip, stubDir + "/" + stubClip.name + ".anim");
            string dataPath = dataDir + "/" + clipData.name + ".asset";

            AssetDatabase.CreateAsset(clipData, dataPath);
            var stateProxy = animatorState.AddStateMachineBehaviour <CompressionAnimatorStateProxy>();

            stateProxy.data = clipData;
            return(dataPath);
        }
示例#19
0
        public override IEnumerable <Object> FetchDependencies(ISerializedFile file, bool isLog = false)
        {
            foreach (Object asset in base.FetchDependencies(file, isLog))
            {
                yield return(asset);
            }

            if (IsReadClassIDToTrack(file.Version, file.Flags))
            {
                foreach (KeyValuePair <int, PPtr <BaseAnimationTrack> > kvp in ClassIDToTrack)
                {
                    yield return(kvp.Value.FetchDependency(file, isLog, () => ValidName, ClassIDToTrackName));
                }
                foreach (ChildTrack track in ChildTracks)
                {
                    foreach (Object asset in track.FetchDependencies(file, isLog))
                    {
                        yield return(asset);
                    }
                }
            }
            if (IsReadCurves(file.Version))
            {
                foreach (FloatCurve curve in FloatCurves)
                {
                    foreach (Object asset in curve.FetchDependencies(file, isLog))
                    {
                        yield return(asset);
                    }
                }
            }
            if (IsReadPPtrCurves(file.Version))
            {
                foreach (PPtrCurve curve in PPtrCurves)
                {
                    foreach (Object asset in curve.FetchDependencies(file, isLog))
                    {
                        yield return(asset);
                    }
                }
            }
            if (IsReadClipBindingConstant(file.Version))
            {
                foreach (Object asset in ClipBindingConstant.FetchDependencies(file, isLog))
                {
                    yield return(asset);
                }
            }
#if UNIVERSAL
            if (IsReadAnimationClipSettings(file.Version, file.Flags))
            {
                foreach (Object asset in AnimationClipSettings.FetchDependencies(file, isLog))
                {
                    yield return(asset);
                }
            }
            if (IsReadEditorCurves(file.Version, file.Flags))
            {
                foreach (FloatCurve editorCurve in EditorCurves)
                {
                    foreach (Object asset in editorCurve.FetchDependencies(file, isLog))
                    {
                        yield return(asset);
                    }
                }
                foreach (FloatCurve eulerEditorCurve in EulerEditorCurves)
                {
                    foreach (Object asset in eulerEditorCurve.FetchDependencies(file, isLog))
                    {
                        yield return(asset);
                    }
                }
            }
#endif
            if (IsReadEvents(file.Version))
            {
                foreach (AnimationEvent @event in Events)
                {
                    foreach (Object asset in @event.FetchDependencies(file, isLog))
                    {
                        yield return(asset);
                    }
                }
            }
        }
示例#20
0
        public static AnimationClip CreateAnimationClip(FPlayAnimationEvent animEvent)
        {
            FAnimationTrack track = (FAnimationTrack)animEvent.Track;

            string animName = ((FAnimationTrack)animEvent.Track).LayerName + "_" + animEvent.GetId().ToString();

            AnimationClip clip = AnimatorController.AllocateAnimatorClip(animName);

            clip.frameRate = animEvent.Sequence.FrameRate;

            Transform ownerTransform = animEvent.Owner;

            Vector3 pos = ownerTransform.localPosition;

            Vector3 rot = ownerTransform.localRotation.eulerAngles;             //ownerTransform.localEulerAngles;

            Keyframe[] xPosKeys = new Keyframe[] { new Keyframe(0, pos.x), new Keyframe(animEvent.LengthTime, pos.x) };
            Keyframe[] yPosKeys = new Keyframe[] { new Keyframe(0, pos.y), new Keyframe(animEvent.LengthTime, pos.y) };
            Keyframe[] zPosKeys = new Keyframe[] { new Keyframe(0, pos.z), new Keyframe(animEvent.LengthTime, pos.z) };

            Keyframe[] xRotKeys = new Keyframe[] { new Keyframe(0, rot.x), new Keyframe(animEvent.LengthTime, rot.x) };
            Keyframe[] yRotKeys = new Keyframe[] { new Keyframe(0, rot.y), new Keyframe(animEvent.LengthTime, rot.y) };
            Keyframe[] zRotKeys = new Keyframe[] { new Keyframe(0, rot.z), new Keyframe(animEvent.LengthTime, rot.z) };

            // set the tangent mode
            int tangentMode = 10;             // 10 is unity auto tangent mode

            for (int i = 0; i != xPosKeys.Length; ++i)
            {
                xPosKeys[i].tangentMode = tangentMode;
                yPosKeys[i].tangentMode = tangentMode;
                zPosKeys[i].tangentMode = tangentMode;

                xRotKeys[i].tangentMode = tangentMode;
                yRotKeys[i].tangentMode = tangentMode;
                zRotKeys[i].tangentMode = tangentMode;
            }

            AnimationCurve xPos = new AnimationCurve(xPosKeys);
            AnimationCurve yPos = new AnimationCurve(yPosKeys);
            AnimationCurve zPos = new AnimationCurve(zPosKeys);

            AnimationCurve xRot = new AnimationCurve(xRotKeys);
            AnimationCurve yRot = new AnimationCurve(yRotKeys);
            AnimationCurve zRot = new AnimationCurve(zRotKeys);

            AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(string.Empty, typeof(Transform), "m_LocalPosition.x"), xPos);
            AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(string.Empty, typeof(Transform), "m_LocalPosition.y"), yPos);
            AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(string.Empty, typeof(Transform), "m_LocalPosition.z"), zPos);

            // workaround unity bug of spilling errors if you just set localEulerAngles
            Quaternion quat = ownerTransform.localRotation;

            Keyframe[]     xQuatKeys = new Keyframe[] { new Keyframe(0, quat.x), new Keyframe(animEvent.LengthTime, quat.x) };
            Keyframe[]     yQuatKeys = new Keyframe[] { new Keyframe(0, quat.y), new Keyframe(animEvent.LengthTime, quat.y) };
            Keyframe[]     zQuatKeys = new Keyframe[] { new Keyframe(0, quat.z), new Keyframe(animEvent.LengthTime, quat.z) };
            Keyframe[]     wQuatKeys = new Keyframe[] { new Keyframe(0, quat.w), new Keyframe(animEvent.LengthTime, quat.w) };
            AnimationCurve xQuat     = new AnimationCurve(xQuatKeys);
            AnimationCurve yQuat     = new AnimationCurve(yQuatKeys);
            AnimationCurve zQuat     = new AnimationCurve(zQuatKeys);
            AnimationCurve wQuat     = new AnimationCurve(wQuatKeys);

            AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(string.Empty, typeof(Transform), "m_LocalRotation.x"), xQuat);
            AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(string.Empty, typeof(Transform), "m_LocalRotation.y"), yQuat);
            AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(string.Empty, typeof(Transform), "m_LocalRotation.z"), zQuat);
            AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(string.Empty, typeof(Transform), "m_LocalRotation.w"), wQuat);

            AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(string.Empty, typeof(Transform), "localEulerAngles.x"), xRot);
            AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(string.Empty, typeof(Transform), "localEulerAngles.y"), yRot);
            AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(string.Empty, typeof(Transform), "localEulerAngles.z"), zRot);

            clip.EnsureQuaternionContinuity();

            AssetDatabase.AddObjectToAsset(clip, track.AnimatorController);

            AnimationClipSettings clipSettings = AnimationUtility.GetAnimationClipSettings(clip);

            clipSettings.loopTime = false;
            AnimationUtility.SetAnimationClipSettings(clip, clipSettings);

            AssetDatabase.SaveAssets();

            FAnimationEventInspector.SetAnimationClip(animEvent, clip);

            return(clip);
        }
    public static void ProcessCharacter()
    {
        // Get the file paths of the data
        string plist_path = EditorUtility.OpenFilePanel("Open character's config data:", "Assets", "plist");
        string json_path  = EditorUtility.OpenFilePanel("Open character's skeletal/animation data:", "Assets", "ExportJson");

        Texture2D sprite;

        if (Selection.objects.Length != 1)
        {
            sprite = null;
        }
        else
        {
            sprite = Selection.activeObject as Texture2D;
        }

        if (sprite == null)
        {
            Debug.LogError("ERROR: Sprite sheet is not selected.");
            return;
        }

        if (plist_path == "" || json_path == "")
        {
            Debug.LogError("ERROR: Plist and/or JSON are null.");
            return;
        }


        // Read sprite data from the plist
        List <SpriteData> cutting_data = ReadPlist(plist_path);

        // Cut sprite data
        List <SpriteMetaData> sheet = CutSprite(sprite, cutting_data);

        // Prepare sprite atlas
        string atlas_source = AssetDatabase.GetAssetPath(sprite);

        atlas_source = atlas_source.Substring(atlas_source.LastIndexOf("/") + 1, (atlas_source.LastIndexOf(".") - atlas_source.LastIndexOf("/")) - 1);
        SpriteAtlas atlas = new SpriteAtlas(atlas_source);


        // Read data from Json file into Json string
        string json_content = File.ReadAllText(json_path);

        // Deserialize Json string into usable object data
        RootObject obj = JsonUtility.FromJson <RootObject>(json_content);


        // Create base object for armature
        GameObject root = new GameObject(obj.armature_data[0].name);

        root.tag = "Armature";

        // Prepare the skeleton
        //List<GameObject> bones = new List<GameObject>();
        List <SpriteBone> bones = new List <SpriteBone>();


        // For each bone in the skeleton
        foreach (BoneData node in obj.armature_data[0].bone_data)
        {
            // Create a new game object, tag is set to bone
            GameObject g = new GameObject(node.name);
            g.tag = "Bone";

            // If parent node is null, parent the object to the root
            if (node.parent == "")
            {
                g.transform.SetParent(root.transform);
            }
            else
            {
                // Get a reference to all child transforms
                Transform[] allChildren = root.GetComponentsInChildren <Transform>();

                // For each transform
                foreach (Transform child in allChildren)
                {
                    // Check if transform name matches parent. If so, parent the object to that transform
                    if (child.gameObject.name == node.parent)
                    {
                        g.transform.SetParent(child);
                    }
                }
            }

            // POSITION IS RELATIVE TO PARENT
            // Set the position and scale
            // Mathf.Rad2Deg
            g.transform.localPosition    = new Vector2((float)node.x / scale_factor, (float)node.y / scale_factor);
            g.transform.localScale       = new Vector3((float)node.cX, (float)node.cY, 1.0f);
            g.transform.localEulerAngles = new Vector3(0.0f, 0.0f, (float)(node.kY * Mathf.Rad2Deg));

            int index        = 0;
            int displayIndex = node.dI;

            /*if (displayIndex < 0)
             *  displayIndex = 0;*/

            // Initialize skeleton
            SpriteBone sb = new SpriteBone();
            sb.bone = g;


            // Sprites need to be their own gameobjects
            foreach (DisplayData d in node.display_data)
            {
                // Create object
                GameObject s = new GameObject(d.name);
                s.transform.SetParent(g.transform);
                s.tag = "Display Data";

                SkinData   d_data = d.skin_data[0];
                SpriteData sd     = FindSpriteData(cutting_data, d.name);

                // Set sprite transforms
                if (sd != null)
                {
                    s.transform.localPosition    = new Vector3(((float)d_data.x) / scale_factor, ((float)d_data.y) / scale_factor);
                    s.transform.localScale       = new Vector3((float)d_data.cX, (float)d_data.cY, 1.0f);
                    s.transform.localEulerAngles = new Vector3(0.0f, 0.0f, (float)(d_data.kY * Mathf.Rad2Deg));

                    // Set sprite offset
                    GameObject o = new GameObject(index.ToString());
                    o.transform.SetParent(s.transform);
                    o.tag = "Sprite";

                    // Set up sprite components
                    o.AddComponent <SpriteRenderer>();
                    //o.GetComponent<SpriteRenderer>().sortingOrder = node.z;
                    Sprite body_piece = atlas.getSprite(d.name);
                    o.GetComponent <SpriteRenderer>().sprite = body_piece;

                    // Apply sprite offset
                    o.transform.localPosition    = new Vector3(sd.offsetX / scale_factor, sd.offsetY / scale_factor, -node.z / scale_factor);
                    o.transform.localEulerAngles = Vector3.zero;

                    sb.displayData.Add(o);

                    // Determine visibility
                    if (displayIndex != index)
                    {
                        o.SetActive(false);
                    }
                }

                index++;
            }

            // Add bone to the list
            bones.Add(sb);
        }


        // Add an animator to the root
        root.AddComponent <Animator>();

        // Create an animator controller (ADDENDUM: MAY NOT BE NEEDED)

        // Loop through all animations in the JSON
        foreach (MovData md in obj.animation_data[0].mov_data)
        {
            // Create and name an animation clip
            AnimationClip anim = new AnimationClip();
            anim.name = md.name;

            // Name and frame index of inverted bones
            // Change to dictionary <string, Dictionary<int, bool>>
            Dictionary <string, Dictionary <int, bool> > toInvert = new Dictionary <string, Dictionary <int, bool> >();

            foreach (MovBoneData mbd in md.mov_bone_data)
            {
                Dictionary <int, bool> boneInv = new Dictionary <int, bool>();
                int numAdded = 0;

                foreach (FrameData fd in mbd.frame_data)
                {
                    if (fd.cX < 0 || fd.cY < 0)
                    {
                        boneInv.Add(fd.fi, true);
                        numAdded++;
                    }
                    else
                    {
                        if (!boneInv.ContainsKey(fd.fi))
                        {
                            boneInv.Add(fd.fi, false);
                        }
                    }
                }

                if (boneInv.Count > 0 && numAdded > 0)
                {
                    toInvert.Add(mbd.name, boneInv);
                }
            }


            // Loop through all bone data
            foreach (MovBoneData mbd in md.mov_bone_data)
            {
                // Name of bone that needs its transform inverted
                //List<string> toInvert = new List<string>();

                // Find the game object matching the bone
                SpriteBone bone = null;

                foreach (SpriteBone sb in bones)
                {
                    if (sb.bone.name.Equals(mbd.name))
                    {
                        bone = sb;
                    }
                }

                // Prepare animation curves for animated properties
                AnimationCurve curve_x  = new AnimationCurve();
                AnimationCurve curve_y  = new AnimationCurve();
                AnimationCurve curve_cx = new AnimationCurve();
                AnimationCurve curve_cy = new AnimationCurve();
                AnimationCurve curve_ky = new AnimationCurve();

                AnimationCurve[] curve_z  = new AnimationCurve[bone.displayData.Count];
                AnimationCurve[] curve_di = new AnimationCurve[bone.displayData.Count];

                AnimationCurve[] curve_fx = new AnimationCurve[bone.displayData.Count];
                AnimationCurve[] curve_fy = new AnimationCurve[bone.displayData.Count];

                // Required to retain offsets
                AnimationCurve[] curve_zx = new AnimationCurve[bone.displayData.Count];
                AnimationCurve[] curve_zy = new AnimationCurve[bone.displayData.Count];

                for (int i = 0; i < bone.displayData.Count; i++)
                {
                    curve_z[i]  = new AnimationCurve();
                    curve_zx[i] = new AnimationCurve();
                    curve_zy[i] = new AnimationCurve();
                    curve_di[i] = new AnimationCurve();
                    curve_fx[i] = new AnimationCurve();
                    curve_fy[i] = new AnimationCurve();
                }

                int previous_z = 0;

                // Loop through all keyframes for that bone
                foreach (FrameData fd in mbd.frame_data)
                {
                    // Set keyframe values for position, rotation, and scale. Note that all of these are relative
                    Keyframe px = new Keyframe((fd.fi / sample_rate), (bone.bone.transform.localPosition.x + ((float)fd.x / scale_factor)));
                    px.tangentMode = 0;
                    px.inTangent   = 0.0f;
                    px.outTangent  = 0.0f;

                    Keyframe py = new Keyframe((fd.fi / sample_rate), (bone.bone.transform.localPosition.y + ((float)fd.y / scale_factor)));
                    py.tangentMode = 0;
                    py.inTangent   = 0.0f;
                    py.outTangent  = 0.0f;

                    curve_x.AddKey(px);
                    curve_y.AddKey(py);

                    // Scale keyframes
                    Keyframe kx = new Keyframe((fd.fi / sample_rate), ((float)fd.cX));
                    kx.tangentMode = 0;
                    kx.inTangent   = 0.0f;
                    kx.outTangent  = 0.0f;

                    Keyframe ky = new Keyframe((fd.fi / sample_rate), ((float)fd.cY));
                    ky.tangentMode = 0;
                    ky.inTangent   = 0.0f;
                    ky.outTangent  = 0.0f;

                    curve_cx.AddKey(kx);
                    curve_cy.AddKey(ky);

                    // This is the ONLY bug remaining. When something's supposed to be inverted, the inversion is never reset.
                    // Inversion is also not 100%. For example, Suzy's right arm is not inverted in her idle animation


                    // Correct inversion error
                    Transform t         = bone.bone.transform;
                    float     direction = 1.0f;

                    while (t.transform.parent != null)
                    {
                        t = t.transform.parent;

                        if (toInvert.ContainsKey(t.gameObject.name))
                        {
                            // This needs to get the previous frame index if none exist
                            if (InvertAtIndex(toInvert, fd.fi, t.gameObject.name))
                            {
                                direction = -1.0f;
                                Debug.Log("Success! - " + md.name + ": " + t.gameObject.name + " " + mbd.name);
                            }
                        }
                    }
                    // Invert rotation
                    Keyframe ry = new Keyframe((fd.fi / sample_rate),
                                               direction * (bone.bone.transform.localEulerAngles.z + ((float)(fd.kY * Mathf.Rad2Deg))));
                    ry.tangentMode = 0;
                    ry.inTangent   = 0.0f;
                    ry.outTangent  = 0.0f;

                    curve_ky.AddKey(ry);

                    // Determine display index
                    int displayIndex = fd.dI;

                    for (int i = 0; i < bone.displayData.Count; i++)
                    {
                        // If the frame index is not one, a second keyframe will need to be set to disable "sliding"
                        if (fd.fi > 1)
                        {
                            Keyframe p_zx = new Keyframe(((fd.fi - 1) / sample_rate), bone.displayData[i].transform.localPosition.x);
                            p_zx.tangentMode = 0;
                            p_zx.inTangent   = 0.0f;
                            p_zx.outTangent  = 0.0f;

                            Keyframe p_zy = new Keyframe(((fd.fi - 1) / sample_rate), bone.displayData[i].transform.localPosition.y);
                            p_zy.tangentMode = 0;
                            p_zy.inTangent   = 0.0f;
                            p_zy.outTangent  = 0.0f;

                            Keyframe p_zz = new Keyframe(((fd.fi - 1) / sample_rate), bone.displayData[i].transform.localPosition.z + (-previous_z / scale_factor));
                            p_zz.tangentMode = 0;
                            p_zz.inTangent   = 0.0f;
                            p_zz.outTangent  = 0.0f;

                            curve_z[i].AddKey(p_zz);
                            curve_zx[i].AddKey(p_zx);
                            curve_zy[i].AddKey(p_zy);
                        }

                        Keyframe zx = new Keyframe((fd.fi / sample_rate), bone.displayData[i].transform.localPosition.x);
                        zx.tangentMode = 0;
                        zx.inTangent   = 0.0f;
                        zx.outTangent  = 0.0f;

                        Keyframe zy = new Keyframe((fd.fi / sample_rate), bone.displayData[i].transform.localPosition.y);
                        zy.tangentMode = 0;
                        zy.inTangent   = 0.0f;
                        zy.outTangent  = 0.0f;

                        Keyframe zz = new Keyframe((fd.fi / sample_rate), bone.displayData[i].transform.localPosition.z + (-fd.z / scale_factor));
                        zz.tangentMode = 0;
                        zz.inTangent   = 0.0f;
                        zz.outTangent  = 0.0f;

                        curve_z[i].AddKey(zz);
                        previous_z = fd.z;

                        curve_zx[i].AddKey(zx);
                        curve_zy[i].AddKey(zy);

                        // Check if the current index equals the display index

                        if (bone.displayData[i].name.Equals(displayIndex.ToString()))
                        {
                            Keyframe k = new Keyframe((fd.fi / sample_rate), 1.0f);
                            k.tangentMode = 103;
                            k.inTangent   = float.PositiveInfinity;
                            k.outTangent  = float.PositiveInfinity;
                            curve_di[i].AddKey(k);
                        }

                        else
                        {
                            Keyframe k = new Keyframe((fd.fi / sample_rate), 0.0f);
                            k.tangentMode = 103;
                            k.inTangent   = float.PositiveInfinity;
                            k.outTangent  = float.PositiveInfinity;
                            curve_di[i].AddKey(k);
                        }
                    }
                }

                // Get full name of bone
                string bone_name = GetCompletePath(bone.bone.transform);

                // Apply transform keyframes to animation clip
                anim.SetCurve(bone_name, typeof(Transform), "localPosition.x", curve_x);
                anim.SetCurve(bone_name, typeof(Transform), "localPosition.y", curve_y);
                anim.SetCurve(bone_name, typeof(Transform), "localScale.x", curve_cx);
                anim.SetCurve(bone_name, typeof(Transform), "localScale.y", curve_cy);
                anim.SetCurve(bone_name, typeof(Transform), "localEulerAngles.z", curve_ky);

                // Get full name of sprites
                string[] sprite_names = new string[bone.displayData.Count];

                for (int i = 0; i < sprite_names.Length; i++)
                {
                    sprite_names[i] = GetCompletePath(bone.displayData[i].transform);

                    // Apply sprite keyframes to animation clip
                    anim.SetCurve(sprite_names[i], typeof(Transform), "localPosition.x", curve_zx[i]);
                    anim.SetCurve(sprite_names[i], typeof(Transform), "localPosition.y", curve_zy[i]);
                    anim.SetCurve(sprite_names[i], typeof(Transform), "localPosition.z", curve_z[i]);

                    anim.SetCurve(sprite_names[i], typeof(GameObject), "m_IsActive", curve_di[i]);
                }
            }

            // Apply loop
            AnimationClipSettings animClipSett = new AnimationClipSettings();
            animClipSett.loopTime = md.lp;

            AnimationUtility.SetAnimationClipSettings(anim, animClipSett);

            string filePath = "assets/animations/" + sprite.name + "/";

            // Create the anim clip
            if (!Directory.Exists(filePath))
            {
                Directory.CreateDirectory(filePath);
            }

            AssetDatabase.CreateAsset(anim, filePath + anim.name + ".anim");
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
        }
    }
示例#22
0
    private static void Compress(AnimationClip src, AnimationClip target, bool reducePrecision)
    {
        AnimationClipSettings settings = AnimationUtility.GetAnimationClipSettings(src);

        EditorCurveBinding[] bindings = AnimationUtility.GetCurveBindings(src);

        AnimationUtility.SetAnimationClipSettings(target, settings);

        float curIdx = 0;

        foreach (var b in bindings)
        {
            curIdx += 1f;
            EditorUtility.DisplayProgressBar("动画压缩", b.path, curIdx / bindings.Length);

            bool isPositionCurve = b.propertyName.IndexOf("Position") > -1;
            bool isScaleCurve    = b.propertyName.IndexOf("Scale") > -1;

            bool isFixedPositionAndScaleNode = false;
            bool isFixedScaleNode            = false;
            bool isFixedPositionNode         = false;
            foreach (var e in _fixedPositionAndScaleNode)
            {
                if (b.path.EndsWith(e))
                {
                    isFixedPositionAndScaleNode = true;
                    break;
                }
            }

            if (!isFixedPositionAndScaleNode)
            {
                foreach (var e in _fixedScaleNode)
                {
                    if (b.path.EndsWith(e))
                    {
                        isFixedScaleNode = true;
                        break;
                    }
                }

                if (!isFixedScaleNode)
                {
                    foreach (var e in _fixedPositionNode)
                    {
                        if (b.path.EndsWith(e))
                        {
                            isFixedPositionNode = true;
                            break;
                        }
                    }
                }
            }

            if (isFixedPositionAndScaleNode)
            {
                if (isPositionCurve || isScaleCurve)
                {
                    continue;
                }
            }
            else if (isFixedScaleNode)
            {
                if (isScaleCurve)
                {
                    continue;
                }
            }
            else if (isFixedPositionNode)
            {
                if (isPositionCurve)
                {
                    continue;
                }
            }

            var c = AnimationUtility.GetEditorCurve(src, b);

            if (reducePrecision)
            {
                ReduceFloatPrecision(c);
            }

            AnimationUtility.SetEditorCurve(target, b, c);
        }
    }
示例#23
0
    static AnimationClip BuildAnimationClip(DirectoryInfo dictorys, string name)
    {
        string animationName = dictorys.Name;

        //查找所有图片,因为我找的测试动画是.jpg
        FileInfo[]    images = dictorys.GetFiles().ToList().Where(x => (x.Extension.ToLower() == ".png" || x.Extension.ToLower() == ".tga")).OrderBy(x => (TurnNumToInt(x.Name))).ToArray();
        AnimationClip clip   = new AnimationClip();

        if (images.Length == 0)
        {
            return(clip);
        }

        EditorCurveBinding curveBinding = new EditorCurveBinding();

        curveBinding.type         = typeof(SpriteRenderer);
        curveBinding.path         = "";
        curveBinding.propertyName = "m_Sprite";

        ObjectReferenceKeyframe[] keyFrames;
        Sprite sprite;
        //动画长度是按秒为单位,1/10就表示1秒切10张图片,根据项目的情况可以自己调节
        float frameTime = 1f / 8f;

        // 最后补一个第一帧
        // 补帧一个第一帧
        if (!name.Contains("DIE") && !name.Contains("SP1") && !name.Contains("SP2"))
        {
            keyFrames = new ObjectReferenceKeyframe[images.Length + 1];
            sprite    = AssetDatabase.LoadAssetAtPath <Sprite>(DataPathToAssetPath(images[0].FullName).Replace("\\", "/"));
            keyFrames[images.Length]       = new ObjectReferenceKeyframe();
            keyFrames[images.Length].time  = frameTime * Mathf.Max(0, (images.Length + 1 - Mathf.Pow(1.07f, images.Length)));
            keyFrames[images.Length].value = sprite;
        }
        else
        {
            keyFrames = new ObjectReferenceKeyframe[images.Length];
        }

        for (int i = 0; i < images.Length; i++)
        {
            sprite = AssetDatabase.LoadAssetAtPath <Sprite>(DataPathToAssetPath(images[i].FullName).Replace("\\", "/"));

            keyFrames[i]       = new ObjectReferenceKeyframe();
            keyFrames[i].time  = frameTime * Mathf.Max(0, (i + 1 - Mathf.Pow(1.07f, i)));
            keyFrames[i].value = sprite;
        }

        //动画帧率,30比较合适
        clip.frameRate = 30;

        //if( fullname.Contains( "Airman" ) )
        //{
        //    if( !name.Contains( "Dth" ) )
        //    {
        //        EditorCurveBinding curve = new EditorCurveBinding();
        //        curve.type = typeof( Transform );
        //        curve.path = "";
        //        curve.propertyName = "m_LocalPosition.y";

        //        AnimationCurve curveAnime = new AnimationCurve();
        //        curveAnime.AddKey( 0f, 2f );
        //        AnimationUtility.SetEditorCurve( clip, curve, curveAnime );
        //    }
        //    else
        //    {
        //        EditorCurveBinding curve = new EditorCurveBinding();
        //        curve.type = typeof( Transform );
        //        curve.path = "";
        //        curve.propertyName = "m_LocalPosition.y";

        //        float lastKey = keyFrames[images.Length - 1].time + frameTime * Mathf.Max( 0, ( 6 + 1 - Mathf.Pow( 1.07f, 6 ) ) );
        //        AnimationCurve curveAnime = new AnimationCurve();
        //        curveAnime.AddKey( 0f, 2f );
        //        curveAnime.AddKey( keyFrames[images.Length - 1].time/2f, 2.5f );
        //        curveAnime.AddKey( lastKey, 0f );
        //        AnimationUtility.SetEditorCurve( clip, curve, curveAnime );


        //        AnimationEvent evt = new AnimationEvent();
        //        evt.time = keyFrames[keyFrames.Length - 1].time;
        //        evt.functionName = "OnDie";
        //        AnimationUtility.SetAnimationEvents( clip, new AnimationEvent[] { evt } );
        //    }
        //}

        // 方向,5,7,翻转
        if (name.Substring(name.Length - 1) == "1" || name.Substring(name.Length - 1) == "2" || name.Substring(name.Length - 1) == "3")
        {
            EditorCurveBinding curve = new EditorCurveBinding();
            curve.type         = typeof(Transform);
            curve.path         = "";
            curve.propertyName = "m_LocalScale.x";

            AnimationCurve curveAnime = new AnimationCurve();
            curveAnime.AddKey(0f, -1f);
            AnimationUtility.SetEditorCurve(clip, curve, curveAnime);

            curve              = new EditorCurveBinding();
            curve.type         = typeof(Transform);
            curve.path         = "";
            curve.propertyName = "m_LocalScale.y";

            curveAnime = new AnimationCurve();
            curveAnime.AddKey(0f, 1f);
            AnimationUtility.SetEditorCurve(clip, curve, curveAnime);

            curve              = new EditorCurveBinding();
            curve.type         = typeof(Transform);
            curve.path         = "";
            curve.propertyName = "m_LocalScale.z";

            curveAnime = new AnimationCurve();
            curveAnime.AddKey(0f, 1f);
            AnimationUtility.SetEditorCurve(clip, curve, curveAnime);
        }
        else
        {
            EditorCurveBinding curve = new EditorCurveBinding();
            curve.type         = typeof(Transform);
            curve.path         = "";
            curve.propertyName = "m_LocalScale.x";

            AnimationCurve curveAnime = new AnimationCurve();
            curveAnime.AddKey(0f, 1f);
            AnimationUtility.SetEditorCurve(clip, curve, curveAnime);

            curve              = new EditorCurveBinding();
            curve.type         = typeof(Transform);
            curve.path         = "";
            curve.propertyName = "m_LocalScale.y";

            curveAnime = new AnimationCurve();
            curveAnime.AddKey(0f, 1f);
            AnimationUtility.SetEditorCurve(clip, curve, curveAnime);

            curve              = new EditorCurveBinding();
            curve.type         = typeof(Transform);
            curve.path         = "";
            curve.propertyName = "m_LocalScale.z";

            curveAnime = new AnimationCurve();
            curveAnime.AddKey(0f, 1f);
            AnimationUtility.SetEditorCurve(clip, curve, curveAnime);
        }


        SerializedObject      serializedClip = new SerializedObject(clip);
        AnimationClipSettings clipSettings   = new AnimationClipSettings(serializedClip.FindProperty("m_AnimationClipSettings"));

        if (name.Contains("ATTACK"))
        {
            clipSettings.loopTime = true;
            serializedClip.ApplyModifiedProperties();

            // 龙的攻击从第一帧开始
            AnimationEvent evt = new AnimationEvent();
            if (name.Contains("Monster11"))
            {
                evt.time = 0;
            }
            else
            {
                // evt.time = keyFrames [images.Length - 1].time - frameTime * Mathf.Max (0, (2 + 1 - Mathf.Pow (1.07f, 2)));
                evt.time = keyFrames [images.Length - 1].time + 0.5f;
            }
            evt.functionName = "OnAttack";

            AnimationUtility.SetAnimationEvents(clip, new AnimationEvent[] { evt });
        }
        else if (name.Contains("DIE"))
        {
            clipSettings.loopTime = false;
            serializedClip.ApplyModifiedProperties();

            AnimationEvent evt = new AnimationEvent();
            evt.time         = keyFrames[keyFrames.Length - 1].time;
            evt.functionName = "OnDie";

            AnimationUtility.SetAnimationEvents(clip, new AnimationEvent[] { evt });
        }
        else if (name.Contains("SP1"))
        {
            clipSettings.loopTime = true;
            serializedClip.ApplyModifiedProperties();

            AnimationEvent evt = new AnimationEvent();
            evt.time         = keyFrames[keyFrames.Length - 1].time;
            evt.functionName = "OnSP1";

            AnimationUtility.SetAnimationEvents(clip, new AnimationEvent[] { evt });
        }
        else if (name.Contains("SP2"))
        {
            clipSettings.loopTime = true;
            serializedClip.ApplyModifiedProperties();

            AnimationEvent evt = new AnimationEvent();
            evt.time         = keyFrames[keyFrames.Length - 1].time;
            evt.functionName = "OnSP2";

            AnimationUtility.SetAnimationEvents(clip, new AnimationEvent[] { evt });
        }
        else
        {
            clipSettings.loopTime = true;
            serializedClip.ApplyModifiedProperties();
        }

        AnimationUtility.SetObjectReferenceCurve(clip, curveBinding, keyFrames);

        return(clip);
    }
示例#24
0
    // GUI Layout for 2D Animation creation function
    void OnGUI()
    {
        if (selectedObject != null)
        {
            //Display the object's name that the animations will be created from
            EditorGUILayout.LabelField("Animations for " + selectedObject.name);
            Object[] sprites     = AssetDatabase.LoadAllAssetsAtPath(AssetDatabase.GetAssetPath(selectedObject));
            int      spriteCount = sprites.Length;
            //Display the number of sprites in the sheet
            EditorGUILayout.LabelField("Number of Sprites: " + spriteCount);
            //create a space
            EditorGUILayout.Separator();
            //Get the name for the animation controller
            controllerName = EditorGUILayout.TextField("Controller Name", controllerName);
            //Determine how many animations there will be
            numAnimations = EditorGUILayout.IntField("How many animations?", numAnimations);

            //Loop through each theoretical animation
            for (int i = 0; i < numAnimations; i++)
            {
                //Determine a name for the animation
                animationNames [i] = EditorGUILayout.TextField("Animation Name", animationNames [i]);

                //Start a section where the items will be displayed horizontally instead of vertically.
                EditorGUILayout.BeginHorizontal();
                //Determine the start frame for the animation
                startFrames [i] = EditorGUILayout.IntField("Start Frame", startFrames [i]);
                //Determine the end frame for the animation
                endFrames [i] = EditorGUILayout.IntField("End Frame", endFrames [i]);
                //End the section where the previous items are displayed horizontally instead of vertically
                EditorGUILayout.EndHorizontal();

                //Start a section where the following items will be displayed horizontally instead of vertically.
                EditorGUILayout.BeginHorizontal();
                //Determine the frame rate for the animation
                clipFrameRate [i] = EditorGUILayout.FloatField("Frame Rate", clipFrameRate [i]);
                //Determine the space between each keyframe
                clipTimeBetween [i] = EditorGUILayout.FloatField("Frame Spacing", clipTimeBetween [i]);
                //End the section where the previous items are displayed horizontally instead of vertically
                EditorGUILayout.EndHorizontal();

                //Start a section where the following items will be displayed horizontally instead of vertically.
                EditorGUILayout.BeginHorizontal();
                //Create a checkbox to determine if this animation should loop
                loop [i] = EditorGUILayout.Toggle("Loop", loop [i]);
                //Create a checkbox to determine if this animation should ping-pong
                pingPong [i] = EditorGUILayout.Toggle("Ping Pong", pingPong [i]);
                //End the section where the previous items are displayed horizontally instead of vertically
                EditorGUILayout.EndHorizontal();

                //Create a space
                EditorGUILayout.Separator();
            }

            //Create a button with the label "Create"
            if (GUILayout.Button("Create"))
            {
                //if the button has been pressed
                //create an animator controller
                UnityEditor.Animations.AnimatorController controller =
                    UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath("Assets/" +
                                                                                             controllerName + ".controller");
                for (int j = 0; j < numAnimations; j++)
                {
                    //if the end frame of an iteration is greater than the total number of frames, a prompt is generated to see
                    //if the user wishes to change it to the last available frame. Otherwise the iteration is skipped
                    if (endFrames[j] > spriteCount)
                    {
                        if (EditorUtility.DisplayDialog("Caution", "End Frame of animation" + j + " exceeds last frame available.\n" +
                                                        "Change to last frame?", "Yes", "No"))
                        {
                            endFrames[j] = spriteCount;
                        }
                        else
                        {
                            continue;
                        }
                    }
                    //create animation clip
                    AnimationClip tempClip = CreateClip(selectedObject, animationNames [j], startFrames [j], endFrames [j],
                                                        clipFrameRate [j], clipTimeBetween [j], pingPong [j]);
                    //determine if the clip should loop
                    if (loop [j])
                    {
                        //set the loop on the clip to true
                        AnimationClipSettings settings = AnimationUtility.GetAnimationClipSettings(tempClip);
                        settings.loopTime  = true;
                        settings.loopBlend = true;
                        AnimationUtility.SetAnimationClipSettings(tempClip, settings);
                    }

                    controller.AddMotion(tempClip);
                }

                CreatePrefab(controller);
            }
        }
    }
		static void SetAnimationSettings (AnimationClip clip, AnimationClipSettings settings) {
			AnimationUtility.SetAnimationClipSettings(clip, settings);
		}
示例#26
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));
        }
示例#27
0
	static void SetAnimationSettings (AnimationClip clip, AnimationClipSettings settings) {
#if UNITY_5
		AnimationUtility.SetAnimationClipSettings(clip, settings);
#else
		MethodInfo methodInfo = typeof(AnimationUtility).GetMethod("SetAnimationClipSettings", BindingFlags.Static | BindingFlags.NonPublic);
		methodInfo.Invoke(null, new object[] { clip, settings });

		EditorUtility.SetDirty(clip);
#endif
	}
        public static AnimationClip BuildAnimationClip(DirectoryInfo dictorys, bool hasAngle = false, bool hasType = false)
        {
            string animationName = dictorys.Name;
            string parentName    = Directory.GetParent(dictorys.FullName).Name;

            if (hasAngle)
            {
                animationName = Directory.GetParent(dictorys.FullName).Name + "_" + dictorys.Name;
                parentName    = Directory.GetParent(Directory.GetParent(dictorys.FullName).FullName).Name;
            }

            if (hasType)
            {
                parentName  = Directory.GetParent(Directory.GetParent(Directory.GetParent(dictorys.FullName).FullName).FullName).Name;
                parentName += "/" + Directory.GetParent(Directory.GetParent(dictorys.FullName).FullName).Name;
            }



            //查找所有图片,因为我找的测试动画是.jpg
            FileInfo []   images = dictorys.GetFiles("*.png");
            AnimationClip clip   = new AnimationClip();
            //		AnimationUtility.SetAnimationType(clip,ModelImporterAnimationType.Generic);
            EditorCurveBinding curveBinding = new EditorCurveBinding();

            curveBinding.type         = typeof(Image);
            curveBinding.path         = "";
            curveBinding.propertyName = "m_Sprite";
            ObjectReferenceKeyframe[] keyFrames = new ObjectReferenceKeyframe[images.Length];
            //动画长度是按秒为单位,1/10就表示1秒切10张图片,根据项目的情况可以自己调节
            float frameTime = 1 / 10f;

            for (int i = 0; i < images.Length; i++)
            {
                Sprite sprite = AssetDatabase.LoadAssetAtPath <Sprite>(DataPathToAssetPath(images[i].FullName));
                keyFrames[i]       = new ObjectReferenceKeyframe();
                keyFrames[i].time  = frameTime * i;
                keyFrames[i].value = sprite;
            }
            //动画帧率,30比较合适
            clip.frameRate = 30;

            //有些动画我希望天生它就动画循环
            if (animationName.IndexOf("idle") >= 0 || animationName.IndexOf("run") >= 0)
            {
                //设置idle文件为循环动画
                SerializedObject      serializedClip = new SerializedObject(clip);
                AnimationClipSettings clipSettings   = new AnimationClipSettings(serializedClip.FindProperty("m_AnimationClipSettings"));
                clipSettings.loopTime = true;
                serializedClip.ApplyModifiedProperties();
            }


            string path = AnimationPath + "/" + parentName + "/" + animationName + ".anim";

            CheckPath(path, true);
            AnimationUtility.SetObjectReferenceCurve(clip, curveBinding, keyFrames);
            AssetDatabase.CreateAsset(clip, path);
            AssetDatabase.SaveAssets();
            return(clip);
        }
示例#29
0
        public override void Read(AssetReader reader)
        {
            base.Read(reader);

            if (IsReadClassIDToTrack(reader.Version, reader.Flags))
            {
                m_classIDToTrack = new Dictionary <int, PPtr <BaseAnimationTrack> >();
                m_classIDToTrack.Read(reader);
                m_childTracks = reader.ReadAssetArray <ChildTrack>();
            }

            if (IsReadAnimationType(reader.Version))
            {
                AnimationType = (AnimationType)reader.ReadInt32();
            }
            if (IsReadLegacy(reader.Version))
            {
                Legacy = reader.ReadBoolean();
            }

            if (IsReadCompressed(reader.Version))
            {
                Compressed = reader.ReadBoolean();
            }
            if (IsReadUseHightQualityCurve(reader.Version))
            {
                UseHightQualityCurve = reader.ReadBoolean();
            }
            if (IsAlignCompressed(reader.Version))
            {
                reader.AlignStream(AlignType.Align4);
            }

            if (IsReadCurves(reader.Version))
            {
                m_rotationCurves = reader.ReadAssetArray <QuaternionCurve>();
            }
            if (IsReadCompressedRotationCurves(reader.Version))
            {
                m_compressedRotationCurves = reader.ReadAssetArray <CompressedAnimationCurve>();
            }
            if (IsReadEulerCurves(reader.Version))
            {
                m_eulerCurves = reader.ReadAssetArray <Vector3Curve>();
            }
            if (IsReadCurves(reader.Version))
            {
                m_positionCurves = reader.ReadAssetArray <Vector3Curve>();
                m_scaleCurves    = reader.ReadAssetArray <Vector3Curve>();
                m_floatCurves    = reader.ReadAssetArray <FloatCurve>();
            }
            if (IsReadPPtrCurves(reader.Version))
            {
                m_PPtrCurves = reader.ReadAssetArray <PPtrCurve>();
            }

            if (IsReadSampleRate(reader.Version))
            {
                SampleRate = reader.ReadSingle();
            }

            if (IsReadWrapMode(reader.Version))
            {
                WrapMode = (WrapMode)reader.ReadInt32();
            }
            if (IsReadBounds(reader.Version))
            {
                Bounds.Read(reader);
            }
            if (IsReadMuscleClip(reader.Version, reader.Flags))
            {
                MuscleClipSize = reader.ReadUInt32();
                MuscleClip     = new ClipMuscleConstant();
                MuscleClip.Read(reader);
            }
            if (IsReadClipBindingConstant(reader.Version))
            {
                ClipBindingConstant.Read(reader);
            }
#if UNIVERSAL
            if (IsReadAnimationClipSettings(reader.Version, reader.Flags))
            {
                AnimationClipSettings = new AnimationClipSettings();
                AnimationClipSettings.Read(reader);
            }
            if (IsReadEditorCurves(reader.Version, reader.Flags))
            {
                m_editorCurves      = reader.ReadAssetArray <FloatCurve>();
                m_eulerEditorCurves = reader.ReadAssetArray <FloatCurve>();
            }
#endif

            if (IsReadHasGenericRootTransform(reader.Version, reader.Flags))
            {
                HasGenericRootTransform = reader.ReadBoolean();
            }
            if (IsReadHasMotionFloatCurves(reader.Version, reader.Flags))
            {
                HasMotionFloatCurves = reader.ReadBoolean();
            }
#if UNIVERSAL
            if (IsReadGenerateMotionCurves(reader.Version, reader.Flags))
            {
                GenerateMotionCurves = reader.ReadBoolean();
            }
#endif
            if (IsReadHasGenericRootTransform(reader.Version, reader.Flags))
            {
                reader.AlignStream(AlignType.Align4);
            }

            if (IsReadEvents(reader.Version))
            {
                m_events = reader.ReadAssetArray <AnimationEvent>();
            }
            if (IsAlign(reader.Version))
            {
                reader.AlignStream(AlignType.Align4);
            }

#if UNIVERSAL
            if (IsReadRuntimeEvents(reader.Version, reader.Flags))
            {
                m_runetimeEvents = reader.ReadAssetArray <AnimationEvent>();
            }
#endif
        }
示例#30
0
    public static AnimationClip BuildAnimationClip(string imageDirect, string animPath)

    {
        string        animationName = Path.GetFileNameWithoutExtension(imageDirect);
        string        textureName   = imageDirect.Replace(".plist", ".png").Replace(Application.dataPath, "Assets");
        var           importer      = AssetImporter.GetAtPath(textureName) as TextureImporter;
        var           imgResources  = AssetDatabase.LoadAllAssetsAtPath(textureName);
        List <Sprite> sprites       = new List <Sprite>();

        foreach (var sprite in imgResources)
        {
            if (sprite is Sprite)
            {
                sprites.Add(sprite as Sprite);
            }
        }
        AnimationClip clip = new AnimationClip();

        //AnimationUtility.SetAnimationType(clip, ModelImporterAnimationType.Generic);

        EditorCurveBinding spriteBinding = new EditorCurveBinding();

        spriteBinding.type         = typeof(SpriteRenderer);
        spriteBinding.path         = "";
        spriteBinding.propertyName = "m_Sprite";
        ObjectReferenceKeyframe[] spriteFrames = new ObjectReferenceKeyframe[sprites.Count];

        AnimationCurve curve = new AnimationCurve();

        //动画长度是按秒为单位,1/10就表示1秒切10张图片,根据项目的情况可以自己调节

        float frameTime = 1 / 10f;

        for (int i = 0; i < sprites.Count; i++)
        {
            spriteFrames[i] = new ObjectReferenceKeyframe();

            spriteFrames[i].time = frameTime * i;

            spriteFrames[i].value = sprites[i];

            var flipFrames = new Keyframe();

            flipFrames.time = frameTime * i;

            if (sprites[i].pivot.x > sprites[i].pivot.y)
            {
                flipFrames.value = 0;
            }
            else
            {
                flipFrames.value = 90;
            }
            flipFrames.inTangent  = 0;
            flipFrames.outTangent = 0;

            curve.AddKey(flipFrames);
        }

        //动画帧率,30比较合适

        clip.frameRate = 30;

        //有些动画我希望天生它就动画循环

        if (animationName.IndexOf("idle") >= 0)

        {
            //设置idle文件为循环动画

            SerializedObject serializedClip = new SerializedObject(clip);

            AnimationClipSettings clipSettings = new AnimationClipSettings();

            clipSettings.loopTime = true;

            serializedClip.ApplyModifiedProperties();
        }

        AnimationUtility.SetObjectReferenceCurve(clip, spriteBinding, spriteFrames);
        clip.SetCurve("", typeof(Transform), "localEulerAnglesRaw.z", curve);


        AssetDatabase.CreateAsset(clip, textureName.Replace(".png", ".anim"));

        AssetDatabase.SaveAssets();

        return(clip);
    }
        private List <AnimationClip> GenerateAnimations(AseFile aseFile, List <Sprite> sprites)
        {
            List <AnimationClip> res = new List <AnimationClip>();
            var animations           = aseFile.GetAnimations();

            if (animations.Length <= 0)
            {
                return(res);
            }

            var metadatas = aseFile.GetMetaData(Settings.spritePivot, Settings.pixelsPerUnit);

            int index = 0;

            foreach (var animation in animations)
            {
                var           path = directoryName + "/" + fileName + "_" + animation.TagName + ".anim";
                AnimationClip clip = AssetDatabase.LoadAssetAtPath <AnimationClip>(path);
                if (clip == null)
                {
                    clip = new AnimationClip();
                    AssetDatabase.CreateAsset(clip, path);
                    clip.wrapMode = GetDefaultWrapMode(animation.TagName);
                }
                else
                {
                    AnimationClipSettings animSettings = AnimationUtility.GetAnimationClipSettings(clip);
                    clip.wrapMode = animSettings.loopTime ? WrapMode.Loop : WrapMode.Once;
                }

                clip.name      = fileName + "_" + animation.TagName;
                clip.frameRate = 25;

                EditorCurveBinding editorBinding = new EditorCurveBinding();
                editorBinding.path         = "";
                editorBinding.propertyName = "m_Sprite";

                switch (Settings.bindType)
                {
                case AseAnimationBindType.SpriteRenderer:
                    editorBinding.type = typeof(SpriteRenderer);
                    break;

                case AseAnimationBindType.UIImage:
                    editorBinding.type = typeof(Image);
                    break;
                }

                // plus last frame to keep the duration
                int length = animation.FrameTo - animation.FrameFrom + 1;
                ObjectReferenceKeyframe[]           spriteKeyFrames = new ObjectReferenceKeyframe[length + 1];
                Dictionary <string, AnimationCurve> transformCurveX = new Dictionary <string, AnimationCurve>(),
                                                    transformCurveY = new Dictionary <string, AnimationCurve>();

                float time = 0;
                int   from = (animation.Animation != LoopAnimation.Reverse) ? animation.FrameFrom : animation.FrameTo;
                int   step = (animation.Animation != LoopAnimation.Reverse) ? 1 : -1;

                int keyIndex = from;
                for (int i = 0; i < length; i++)
                {
                    if (i >= length)
                    {
                        keyIndex = from;
                    }

                    ObjectReferenceKeyframe frame = new ObjectReferenceKeyframe();
                    frame.time  = time;
                    frame.value = sprites[keyIndex];

                    time += aseFile.Frames[keyIndex].FrameDuration / 1000f;
                    spriteKeyFrames[i] = frame;

                    foreach (var metadata in metadatas)
                    {
                        if (metadata.Type == MetaDataType.TRANSFORM && metadata.Transforms.ContainsKey(keyIndex))
                        {
                            var childTransform = metadata.Args[0];
                            if (!transformCurveX.ContainsKey(childTransform))
                            {
                                transformCurveX[childTransform] = new AnimationCurve();
                                transformCurveY[childTransform] = new AnimationCurve();
                            }
                            var pos = metadata.Transforms[keyIndex];
                            transformCurveX[childTransform].AddKey(i, pos.x);
                            transformCurveY[childTransform].AddKey(i, pos.y);
                        }
                    }

                    keyIndex += step;
                }

                float frameTime = 1f / clip.frameRate;
                ObjectReferenceKeyframe lastFrame = new ObjectReferenceKeyframe();
                lastFrame.time  = time - frameTime;
                lastFrame.value = sprites[keyIndex - step];

                spriteKeyFrames[spriteKeyFrames.Length - 1] = lastFrame;
                foreach (var metadata in metadatas)
                {
                    if (metadata.Type == MetaDataType.TRANSFORM && metadata.Transforms.ContainsKey(keyIndex - step))
                    {
                        var childTransform = metadata.Args[0];
                        var pos            = metadata.Transforms[keyIndex - step];
                        transformCurveX[childTransform].AddKey(spriteKeyFrames.Length - 1, pos.x);
                        transformCurveY[childTransform].AddKey(spriteKeyFrames.Length - 1, pos.y);
                    }
                }

                AnimationUtility.SetObjectReferenceCurve(clip, editorBinding, spriteKeyFrames);
                foreach (var childTransform in transformCurveX.Keys)
                {
                    EditorCurveBinding
                             bindingX = new EditorCurveBinding {
                        path         = childTransform,
                        type         = typeof(Transform),
                        propertyName = "m_LocalPosition.x"
                    },
                             bindingY = new EditorCurveBinding {
                        path         = childTransform,
                        type         = typeof(Transform),
                        propertyName = "m_LocalPosition.y"
                    };
                    MakeConstant(transformCurveX[childTransform]);
                    AnimationUtility.SetEditorCurve(clip, bindingX, transformCurveX[childTransform]);
                    MakeConstant(transformCurveY[childTransform]);
                    AnimationUtility.SetEditorCurve(clip, bindingY, transformCurveY[childTransform]);
                }

                AnimationClipSettings clipSettings = AnimationUtility.GetAnimationClipSettings(clip);
                clipSettings.loopTime = (clip.wrapMode == WrapMode.Loop);

                AnimationUtility.SetAnimationClipSettings(clip, clipSettings);
                EditorUtility.SetDirty(clip);
                index++;
                res.Add(clip);
            }

            return(res);
        }
        public override void Read(AssetReader reader)
        {
            base.Read(reader);

            if (HasClassIDToTrack(reader.Version, reader.Flags))
            {
                ClassIDToTrack = new Dictionary <int, PPtr <BaseAnimationTrack> >();
                ClassIDToTrack.Read(reader);
                ChildTracks = reader.ReadAssetArray <ChildTrack>();
            }

            if (HasAnimationType(reader.Version))
            {
                AnimationType = (AnimationType)reader.ReadInt32();
            }
            if (HasLegacy(reader.Version))
            {
                Legacy = reader.ReadBoolean();
            }

            if (HasCompressed(reader.Version))
            {
                Compressed = reader.ReadBoolean();
            }
            if (HasUseHightQualityCurve(reader.Version))
            {
                UseHightQualityCurve = reader.ReadBoolean();
            }
            if (IsAlignCompressed(reader.Version))
            {
                reader.AlignStream();
            }

            if (HasCurves(reader.Version))
            {
                RotationCurves = reader.ReadAssetArray <QuaternionCurve>();
            }
            if (HasCompressedRotationCurves(reader.Version))
            {
                CompressedRotationCurves = reader.ReadAssetArray <CompressedAnimationCurve>();
            }
            if (HasEulerCurves(reader.Version))
            {
                EulerCurves = reader.ReadAssetArray <Vector3Curve>();
            }
            if (HasCurves(reader.Version))
            {
                PositionCurves = reader.ReadAssetArray <Vector3Curve>();
                ScaleCurves    = reader.ReadAssetArray <Vector3Curve>();
                FloatCurves    = reader.ReadAssetArray <FloatCurve>();
            }
            if (HasPPtrCurves(reader.Version))
            {
                PPtrCurves = reader.ReadAssetArray <PPtrCurve>();
            }

            if (HasSampleRate(reader.Version))
            {
                SampleRate = reader.ReadSingle();
            }

            if (HasWrapMode(reader.Version))
            {
                WrapMode = (WrapMode)reader.ReadInt32();
            }
            if (HasBounds(reader.Version))
            {
                Bounds.Read(reader);
            }
            if (HasMuscleClip(reader.Version, reader.Flags))
            {
                MuscleClipSize = reader.ReadUInt32();
                MuscleClip     = new ClipMuscleConstant();
                MuscleClip.Read(reader);
            }
            if (HasClipBindingConstant(reader.Version))
            {
                ClipBindingConstant.Read(reader);
            }
#if UNIVERSAL
            if (HasAnimationClipSettings(reader.Version, reader.Flags))
            {
                AnimationClipSettings = new AnimationClipSettings();
                AnimationClipSettings.Read(reader);
            }
            if (HasEditorCurves(reader.Version, reader.Flags))
            {
                EditorCurves      = reader.ReadAssetArray <FloatCurve>();
                EulerEditorCurves = reader.ReadAssetArray <FloatCurve>();
            }
#endif

            if (HasHasGenericRootTransform(reader.Version, reader.Flags))
            {
                HasGenericRootTransform = reader.ReadBoolean();
            }
            if (HasHasMotionFloatCurves(reader.Version, reader.Flags))
            {
                HasMotionFloatCurves = reader.ReadBoolean();
            }
#if UNIVERSAL
            if (HasGenerateMotionCurves(reader.Version, reader.Flags))
            {
                GenerateMotionCurves = reader.ReadBoolean();
            }
            if (HasIsEmpty(reader.Version, reader.Flags))
            {
                IsEmpty = reader.ReadBoolean();
            }
#endif
            if (HasHasGenericRootTransform(reader.Version, reader.Flags))
            {
                reader.AlignStream();
            }

            if (HasEvents(reader.Version))
            {
                Events = reader.ReadAssetArray <AnimationEvent>();
            }
            if (IsAlign(reader.Version))
            {
                reader.AlignStream();
            }

#if UNIVERSAL
            if (HasRuntimeEvents(reader.Version, reader.Flags))
            {
                RunetimeEvents = reader.ReadAssetArray <AnimationEvent>();
            }
#endif
        }
示例#33
0
    // Use this for initialization
    public void Run()
    {
        Debug.Log("Baking the following animations....");
        List <AnimationClip> animClips = GetAnimationLengths();

        bones = GetListBones();

        for (int j = 0; j < animClips.Count; j++)
        {
            newClip = new AnimationClip();

            //AnimatorStateInfo state =  transform.GetComponent<Animator> ().GetCurrentAnimatorStateInfo(0);
            //float leng = state.length;

            clip = animClips[j];
            float leng = clip.length;
            //Debug.Log(leng);

            curvePosX.Clear(); curvePosY.Clear(); curvePosZ.Clear();
            curveRotX.Clear();      curveRotY.Clear(); curveRotZ.Clear(); curveRotW.Clear();
            curveScaleX.Clear(); curveScaleY.Clear(); curveScaleZ.Clear();

            for (int i = 0; i < bones.Count; i++)
            {
                curvePosX.Add(new AnimationCurve());
                curvePosY.Add(new AnimationCurve());
                curvePosZ.Add(new AnimationCurve());
                curveRotX.Add(new AnimationCurve());
                curveRotY.Add(new AnimationCurve());
                curveRotZ.Add(new AnimationCurve());
                curveRotW.Add(new AnimationCurve());
                curveScaleX.Add(new AnimationCurve());
                curveScaleY.Add(new AnimationCurve());
                curveScaleZ.Add(new AnimationCurve());
            }


            //Time.timeScale = 0.0f;
            //float _lastRealTime = 0.0f;
            frameTime = 1f / clip.frameRate;
            float numFramesInAnim = (leng * clip.frameRate);



            for (int i = 0; i < numFramesInAnim + 1; i++)
            {
                AnimationMode.StartAnimationMode();
                AnimationMode.BeginSampling();
                AnimationMode.SampleAnimationClip(transform.gameObject, clip, i * frameTime);
                transform.GetComponent <Puppet2D_GlobalControl>().Run();

                foreach (Transform bone in bones)
                {
                    bakeAnimation(bone, i * frameTime);
                }
            }
            AnimationMode.EndSampling();
            AnimationMode.StopAnimationMode();



            newClip.name     = clip.name + "_Baked";
            newClip.wrapMode = clip.wrapMode;
            AnimationClipSettings animClipSettings = new AnimationClipSettings();
            animClipSettings.stopTime = clip.length;


            AnimationUtility.SetAnimationType(newClip, ModelImporterAnimationType.Generic);
            SaveAnimationClip(newClip);

            AnimationEvent[] events = new AnimationEvent[1];
            events[0]      = new AnimationEvent();
            events[0].time = clip.length;
            AnimationUtility.SetAnimationEvents(newClip, events);
            AnimationEvent[] events2 = new AnimationEvent[0];
            AnimationUtility.SetAnimationEvents(newClip, events2);

            /*AnimationClipCurveData[] curveDatas = AnimationUtility.GetAllCurves(newClip, true);
             * for (int i=0; i<curveDatas.Length; i++)
             * {
             *      AnimationUtility.SetEditorCurve(
             *              newClip,
             *              curveDatas[i].path,
             *              curveDatas[i].type,
             *              curveDatas[i].propertyName,
             *              curveDatas[i].curve
             *              );
             * }*/

            AssetDatabase.SaveAssets();

            UnityEngine.Object[] newSelection = new UnityEngine.Object[Selection.objects.Length + 1];
            for (int i = 0; i < Selection.objects.Length; i++)
            {
                newSelection [i] = Selection.objects [i];
            }
            newSelection [newSelection.Length - 1] = newClip;
            Selection.objects = newSelection;

            /*
             * transform.GetComponent<Animator> ().StartRecording (0);
             *
             *
             * Invoke ("stopRecording", leng);
             */
        }
        Debug.Log("Finished Baking.");
    }
示例#34
0
    // Use this for initialization
    public void Run()
    {
        Debug.Log("Baking the following animations....");
        List<AnimationClip> animClips = GetAnimationLengths();
        bones = GetListBones () ;

        for (int j = 0; j < animClips.Count; j++)
        {
            newClip = new AnimationClip();

            //AnimatorStateInfo state =  transform.GetComponent<Animator> ().GetCurrentAnimatorStateInfo(0);
            //float leng = state.length;

            clip = animClips[j];
            float leng = clip.length;
            //Debug.Log(leng);

            curvePosX.Clear();curvePosY.Clear();curvePosZ.Clear();
            curveRotX.Clear();	curveRotY.Clear();curveRotZ.Clear();curveRotW.Clear();
            curveScaleX.Clear();curveScaleY.Clear();curveScaleZ.Clear();

            for (int i = 0; i < bones.Count; i++)
            {
                curvePosX.Add (new AnimationCurve());
                curvePosY.Add (new AnimationCurve());
                curvePosZ.Add (new AnimationCurve());
                curveRotX.Add (new AnimationCurve());
                curveRotY.Add (new AnimationCurve());
                curveRotZ.Add (new AnimationCurve());
                curveRotW.Add (new AnimationCurve());
                curveScaleX.Add (new AnimationCurve());
                curveScaleY.Add (new AnimationCurve());
                curveScaleZ.Add (new AnimationCurve());

            }

            //Time.timeScale = 0.0f;
            //float _lastRealTime = 0.0f;
            frameTime = 1f/clip.frameRate;
            float numFramesInAnim = (leng*clip.frameRate);

            for(int i =0;i<numFramesInAnim+1;i++)
            {
                AnimationMode.StartAnimationMode();
                AnimationMode.BeginSampling();
                AnimationMode.SampleAnimationClip (transform.gameObject, clip, i*frameTime);
                transform.GetComponent<Puppet2D_GlobalControl>().Run();

                foreach(Transform bone in bones)
                    bakeAnimation(bone,i*frameTime);

            }
            AnimationMode.EndSampling();
            AnimationMode.StopAnimationMode();

            newClip.name = clip.name + "_Baked";
            newClip.wrapMode = clip.wrapMode;
            AnimationClipSettings animClipSettings = new AnimationClipSettings();
            animClipSettings.stopTime = clip.length;
            #if UNITY_5_1
            newClip.legacy = false;
            #else
            AnimationUtility.SetAnimationType(newClip, ModelImporterAnimationType.Generic);
            #endif
            SaveAnimationClip( newClip );

            AnimationEvent[] events = new AnimationEvent[1];
            events[0] = new AnimationEvent();
            events[0].time = clip.length;
            AnimationUtility.SetAnimationEvents(newClip, events);
            AnimationEvent[] events2 = new AnimationEvent[0];
            AnimationUtility.SetAnimationEvents(newClip, events2);
            /*AnimationClipCurveData[] curveDatas = AnimationUtility.GetAllCurves(newClip, true);
            for (int i=0; i<curveDatas.Length; i++)
            {
                AnimationUtility.SetEditorCurve(
                    newClip,
                    curveDatas[i].path,
                    curveDatas[i].type,
                    curveDatas[i].propertyName,
                    curveDatas[i].curve
                    );
            }*/

            AssetDatabase.SaveAssets();

            UnityEngine.Object[] newSelection = new UnityEngine.Object[Selection.objects.Length + 1];
            for (int i = 0; i < Selection.objects.Length; i++)
            {
                newSelection [i] = Selection.objects [i];

            }
            newSelection [newSelection.Length - 1] = newClip;
            Selection.objects = newSelection;
            /*
            transform.GetComponent<Animator> ().StartRecording (0);

            Invoke ("stopRecording", leng);
            */
        }
        Debug.Log("Finished Baking.");
    }
    void OnGUI()
    {
        if (GUILayout.Button("Get Sprite Editor Data"))
        {
            GetTextureToSpriteData();
        }

        GUILayout.Label("Name");
        sTxt = GUILayout.TextField(sTxt);
        GUILayout.Label("Sprite Folder");
        Folder = EditorGUILayout.ObjectField(Folder, typeof(Object));

        bLoop = GUILayout.Toggle(bLoop, "Loop");
        string sPath = "";

        bUseTagName = GUILayout.Toggle(bUseTagName, "Use Tag Name");
        nFrameRate  = int.Parse(GUILayout.TextField(nFrameRate.ToString()));
        for (int i = 0; i < FolderList.Count; i++)
        {
            GUILayout.BeginHorizontal();

            GUILayout.Label(AssetDatabase.GetAssetPath(FolderList[i].PackingObject) + " / " + FolderList[i].PackingTag + " / " + FolderList[i].Loop);
            if (GUILayout.Button("X", GUILayout.Width(20)))
            {
                FolderList.RemoveAt(i);
            }
            bool bEachLoop = FolderList[i].Loop;

            bEachLoop = GUILayout.Toggle(bEachLoop, "Loop");

            if (bEachLoop != FolderList[i].Loop)
            {
                FolderList[i].Loop = bEachLoop;
            }

            GUILayout.EndHorizontal();
        }

        if (GUILayout.Button("Add") || EnterDown)
        {
            EnterDown = false;
            if (sTxt != string.Empty)
            {
                CreateSpriteAnimationStruct ttss = new CreateSpriteAnimationStruct();

                if (bUseTagName)
                {
                    sPath = AssetDatabase.GetAssetPath(Folder);

                    string[] files = Directory.GetFiles(sPath, "*.png");

                    TextureImporter importer = TextureImporter.GetAtPath(files[0]) as TextureImporter;
                    sTxt = importer.spritePackingTag;
                }

                ttss.PackingTag    = sTxt;
                ttss.PackingObject = Folder;
                ttss.Loop          = bLoop;
                FolderList.Add(ttss);
            }
        }



        if (GUILayout.Button("Create"))
        {
            if (Folder == null || sTxt == "")
            {
                return;
            }

            for (int j = 0; j < FolderList.Count; j++)
            {
                sPath = AssetDatabase.GetAssetPath(FolderList[j].PackingObject);

                string[] files = Directory.GetFiles(sPath, "*.png");

                List <Sprite> listSprite = new List <Sprite>();

                for (int i = 0; i < files.Length; i++)
                {
                    //string sName = files[i].Split('\'')
                    listSprite.Add(AssetDatabase.LoadAssetAtPath <Sprite>(files[i]));
                }

                Animation             anim = new Animation();
                AnimationClip         clip = new AnimationClip();
                AnimationClipSettings sts  = AnimationUtility.GetAnimationClipSettings(clip);
                clip.frameRate = nFrameRate;
                if (FolderList[j].Loop)
                {
                    clip.wrapMode = WrapMode.Loop;
                    sts.loopTime  = true;
                    AnimationUtility.SetAnimationClipSettings(clip, sts);
                }

                sTxt = FolderList[j].PackingTag;

                //System.IO.
                EditorCurveBinding spriteBinding = EditorCurveBinding.PPtrCurve("", typeof(UnityEngine.UI.Image), "m_Sprite");



                //spriteBinding.type = typeof(SpriteRenderer);
                //spriteBinding.path = "";
                //spriteBinding.propertyName = "m_Sprite";



                ObjectReferenceKeyframe[] spriteKeyFrames = new ObjectReferenceKeyframe[listSprite.Count];

                Debug.Log(sPath + "/" + " :: " + files.Length + " listSprite.Length] :: " + listSprite.Count);

                for (int i = 0; i < (listSprite.Count); i++)
                {
                    spriteKeyFrames[i]       = new ObjectReferenceKeyframe();
                    spriteKeyFrames[i].time  = i / clip.frameRate;
                    spriteKeyFrames[i].value = listSprite[i];
                }
                AnimationUtility.SetObjectReferenceCurve(clip, spriteBinding, spriteKeyFrames);
                //clip.setc

                //폴더명 CreatedAnimation
                AssetDatabase.CreateAsset(clip, "assets/CreatedAnimation/" + sTxt + ".anim");
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();

                EditorUtility.DisplayProgressBar("Progress Bar", "Now : " + (j + 1).ToString() + " Changing.....", (float)j / (float)FolderList.Count);
            }
            EditorUtility.ClearProgressBar();
        }
    }
示例#36
0
        private void Export()
        {
            List <AnimationClip> clips = new List <AnimationClip>();

            foreach (Direction direction in billboard.directions)
            {
                AnimationClip clip = new AnimationClip();
                clip.name     = billboard.name + "_" + direction.angleStart + "_" + direction.angleEnd;
                clip.wrapMode = billboard.loop ? WrapMode.Loop : WrapMode.Default;
                AnimationClipSettings settings = new AnimationClipSettings();
                settings.loopTime = billboard.loop;
                AnimationUtility.SetAnimationClipSettings(clip, settings);
                clip.ClearCurves();
                if (direction.sprites.Count != 0)
                {
                    //Set Keyframes
                    EditorCurveBinding curveBinding = new EditorCurveBinding();
                    curveBinding.type         = typeof(SpriteRenderer);
                    curveBinding.path         = "";
                    curveBinding.propertyName = "m_Sprite";
                    ObjectReferenceKeyframe[] keyFrames = new ObjectReferenceKeyframe[direction.sprites.Count];
                    for (int i = 0; i < direction.sprites.Count; i++)
                    {
                        Sprite sprite = direction.sprites[i];
                        keyFrames[i]       = new ObjectReferenceKeyframe();
                        keyFrames[i].time  = i * billboard.waitTime;
                        keyFrames[i].value = sprite;
                    }
                    AnimationUtility.SetObjectReferenceCurve(clip, curveBinding, keyFrames);

                    //Set FlipX
                    AnimationCurve curve = direction.invertSprites
                        ? AnimationCurve.Constant(0, (direction.sprites.Count) * billboard.waitTime, 1)
                        : AnimationCurve.Constant(0, direction.sprites.Count * billboard.waitTime, 0);

                    clip.SetCurve("", typeof(SpriteRenderer), "m_FlipX", curve);
                }
                clips.Add(clip);
            }

            string path = EditorUtility.SaveFilePanelInProject("Export Animations", "animations", "", "Export Animations");

            if (path == "")
            {
                return;
            }

            foreach (AnimationClip clip in clips)
            {
                string clipPath = path + clip.name + ".anim";
                AssetDatabase.CreateAsset(clip, clipPath);
            }

            AssetDatabase.SaveAssets();

            AnimatorController   controller       = null;
            AnimatorStateMachine rootStateMachine = null;

            switch (animator)
            {
            case null:
                controller = AnimatorController.CreateAnimatorControllerAtPath(path + ".controller");
                controller.AddParameter("angle", AnimatorControllerParameterType.Float);
                break;

            default:
                controller = animator;
                break;
            }

            rootStateMachine = controller.layers[0].stateMachine;
            AnimatorStateMachine stateMachine = rootStateMachine.AddStateMachine(billboard.name, Vector3.zero);
            AnimatorState        baseState    = stateMachine.AddState("Base", new Vector3(0, 600));

            for (int x = 0; x < billboard.directions.Count; x++)
            {
                Direction     direction = billboard.directions[x];
                string        name      = billboard.name + "_" + direction.angleStart + "_" + direction.angleEnd;
                AnimationClip clip      = AssetDatabase.LoadAssetAtPath <AnimationClip>(path + name + ".anim");

                float   radians = (((float)x / (billboard.directions.Count)) * 360f) * Mathf.Deg2Rad;
                var     cos     = Mathf.Cos(radians);
                var     sin     = Mathf.Sin(radians);
                Vector3 pos     = new Vector3(0, 600);
                pos += new Vector3(cos, sin) * 300;

                AnimatorState state = stateMachine.AddState(name, pos);
                state.motion = clip;
                var transition = AddTransition(state, baseState);
                transition.AddCondition(AnimatorConditionMode.Greater, direction.angleEnd, "angle");

                transition = AddTransition(state, baseState);
                transition.AddCondition(AnimatorConditionMode.Less, direction.angleStart, "angle");


                transition = AddTransition(baseState, state);
                transition.AddCondition(AnimatorConditionMode.Greater, direction.angleStart, "angle");
                transition.AddCondition(AnimatorConditionMode.Less, direction.angleEnd, "angle");
            }
            AssetDatabase.SaveAssets();
        }
        /// <summary>
        /// Instantiates an <see cref="AnimationClip"/>.
        /// </summary>
        /// <returns>The instantiated clip on success; <see langword="null"/> otherwise.</returns>
        public AnimationClip ToAnimationClip()
        {
            // Check béziers restriction flag.
            if (!Meta.AreBeziersRestricted)
            {
                Debug.LogWarning("Béziers are not restricted and curves might be off. Please export motions from Cubism in restricted mode for perfect match.");
            }


            // Create animation clip.
            var animationClip = new AnimationClip
            {
                frameRate = Meta.Fps
            };


            // Convert curves.
            for (var i = 0; i < Curves.Length; ++i)
            {
                var curve = Curves[i];


                var relativePath   = string.Empty;
                var type           = default(Type);
                var propertyName   = string.Empty;
                var animationCurve = new AnimationCurve(ConvertCurveSegmentsToKeyframes(curve.Segments));


                // Create model binding.
                if (curve.Target == "Model")
                {
                    // Bind opacity.
                    if (curve.Id == "Opacity")
                    {
                        relativePath = string.Empty;
                        propertyName = "Opacity";
                        type         = typeof(CubismRenderController);
                    }

                    // Bind eye-blink.
                    else if (curve.Id == "EyeBlink")
                    {
                        relativePath = string.Empty;
                        propertyName = "EyeOpening";
                        type         = typeof(CubismEyeBlinkController);
                    }

                    // Bind lip-sync.
                    else if (curve.Id == "LipSync")
                    {
                        relativePath = string.Empty;
                        propertyName = "MouthOpening";
                        type         = typeof(CubismMouthController);
                    }
                }

                // Create parameter binding.
                else if (curve.Target == "Parameter")
                {
                    relativePath = "Parameters/" + curve.Id;
                    propertyName = "Value";
                    type         = typeof(CubismParameter);
                }

                // Create part opacity binding.
                else if (curve.Target == "PartOpacity")
                {
                    relativePath = "Parts/" + curve.Id;
                    propertyName = "Opacity";
                    type         = typeof(CubismPart);
                }


#if UNITY_EDITOR
                var curveBinding = new EditorCurveBinding
                {
                    path         = relativePath,
                    propertyName = propertyName,
                    type         = type
                };


                AnimationUtility.SetEditorCurve(animationClip, curveBinding, animationCurve);
#else
                animationClip.SetCurve(relativePath, type, propertyName, animationCurve);
#endif
            }


#if UNITY_EDITOR
            // Apply settings.
            var animationClipSettings = new AnimationClipSettings
            {
                loopTime = Meta.Loop,
                stopTime = Meta.Duration
            };


            AnimationUtility.SetAnimationClipSettings(animationClip, animationClipSettings);
#endif


            return(animationClip);
        }
示例#38
0
    // public method

    #endregion "public method"

    #region "private method"
    // private method

    private void _ConvertAnim(string newClipAssetPath)
    {
        // 0. prepare
        if (!m_Animator.isHuman)
        {
            Dbg.LogWarn("MuscleClipConverterEditor._ConvertAnim: Need to change to Humanoid rig first!");
            return;
        }

        m_SMR = m_Animator.GetComponentInChildren <SkinnedMeshRenderer>();
        if (m_SMR == null)
        {
            Dbg.LogWarn("MuscleClipConverterEditor._ConvertAnim: failed to find SMR under {0}", m_Animator.name);
            return;
        }

        m_Animator.Update(0);
#if !U5
        var ainfos = m_Animator.GetCurrentAnimationClipState(0); //only effect after Update is called
#else
        var ainfos = m_Animator.GetCurrentAnimatorClipInfo(0);   //only effect after Update is called
#endif
        AnimationClip         clip        = ainfos[0].clip;
        AnimationClipSettings clipSetting = AnimationUtility.GetAnimationClipSettings(clip);

        //{//debug
        //    var bindings = AnimationUtility.GetCurveBindings(clip);
        //    foreach( var b in bindings)
        //    {
        //        Dbg.Log("path: {0}, prop: {1}", b.path, b.propertyName);
        //    }
        //}

        Transform animatorTr = m_Animator.transform;
        Transform hipsBone   = null;
        CurveDict curveDict  = new CurveDict();

        float SAMPLE_RATE = clip.frameRate;
        float clipLen     = clip.length;

        Matrix4x4 animatorInitW2LMat = animatorTr.worldToLocalMatrix;
        Matrix4x4 hipsInitW2LMat     = Matrix4x4.identity;

        List <Transform> boneLst = new List <Transform>();
        for (HumanBodyBones boneIdx = 0; boneIdx < HumanBodyBones.LastBone; ++boneIdx)
        {
            Transform tr = m_Animator.GetBoneTransform(boneIdx);
            //Dbg.Log("Map: {0}->{1}", boneIdx, tr);
            if (tr != null)
            {
                boneLst.Add(tr);
                if (boneIdx == HumanBodyBones.Hips)
                {
                    hipsBone       = tr;
                    hipsInitW2LMat = hipsBone.parent.worldToLocalMatrix;
                    //clipSetting.level = -hipsBone.localPosition.y; // set Y offset
                    clipSetting.keepOriginalPositionY = false; //use RootNode position
                }
            }
        }
        Transform[] bones = boneLst.ToArray();

        // init curves for each bone
        for (int idx = 0; idx < bones.Length; ++idx)
        {
            Transform oneBone = bones[idx];
            string    trPath  = AnimationUtility.CalculateTransformPath(oneBone, animatorTr);

            var curves = new _Curves();
            curves.relPath = trPath;

            curveDict.Add(oneBone, curves);
        }

        // init rootmotion curve
        {
            var curves = new _Curves();
            curveDict.Add(animatorTr, curves);
        }

        AnimatorStateInfo curStateInfo = m_Animator.GetCurrentAnimatorStateInfo(0);
        float             nt           = curStateInfo.normalizedTime;
        m_Animator.Update(-nt * clipLen); //revert to 0 time

        {                                 // 1. bake animation info into curve on all bones transform
            float time      = 0f;
            float deltaTime = 1f / (SAMPLE_RATE);
            for (;
                 time <= clipLen || Mathf.Approximately(time, clipLen);
                 )
            {
                //Dbg.Log("nt = {0}", m_Animator.GetCurrentAnimatorStateInfo(0).normalizedTime);

                // bone
                for (int idx = 0; idx < bones.Length; ++idx)
                {
                    Transform oneBone = bones[idx];
                    _Curves   curves  = curveDict[oneBone];

                    if (oneBone == hipsBone)
                    {
                        continue; //skip the HipsBone. This is to add rootMotion matrix on hips, so Legacy is right
                    }
                    Vector3    pos = oneBone.localPosition;
                    Quaternion rot = oneBone.localRotation;

                    curves.X.AddKey(time, rot.x);
                    curves.Y.AddKey(time, rot.y);
                    curves.Z.AddKey(time, rot.z);
                    curves.W.AddKey(time, rot.w);

                    curves.PX.AddKey(time, pos.x);
                    curves.PY.AddKey(time, pos.y);
                    curves.PZ.AddKey(time, pos.z);
                }

                // root motion process
                {
                    { //on Animator transform
                        Vector3 pos = /*animatorTr.localPosition*/ animatorTr.position;
                        Vector3 fwd = animatorTr.forward;
                        Vector3 up  = animatorTr.up;

                        _Curves rootMotionCurves = curveDict[animatorTr];
                        Vector3 lpos             = animatorInitW2LMat.MultiplyPoint(pos);
                        Vector3 lfwd             = animatorInitW2LMat.MultiplyVector(fwd);
                        Vector3 lup = animatorInitW2LMat.MultiplyVector(up);

                        Quaternion rot = Quaternion.LookRotation(lfwd, lup);

                        rootMotionCurves.X.AddKey(time, rot.x);
                        rootMotionCurves.Y.AddKey(time, rot.y);
                        rootMotionCurves.Z.AddKey(time, rot.z);
                        rootMotionCurves.W.AddKey(time, rot.w);

                        rootMotionCurves.PX.AddKey(time, lpos.x);
                        rootMotionCurves.PY.AddKey(time, lpos.y);
                        rootMotionCurves.PZ.AddKey(time, lpos.z);
                    }

                    { //on hips transform
                        if (hipsBone != null)
                        {
                            Vector3 pos = hipsBone.position;
                            Vector3 fwd = hipsBone.forward;
                            Vector3 up  = hipsBone.up;

                            _Curves hipsCurves = curveDict[hipsBone];
                            Vector3 lpos       = hipsInitW2LMat.MultiplyPoint(pos);
                            Vector3 lfwd       = hipsInitW2LMat.MultiplyVector(fwd);
                            Vector3 lup        = hipsInitW2LMat.MultiplyVector(up);

                            //Dbg.Log("time: {0}, lpos: {1}", time, lpos.ToString("F2"));

                            Quaternion rot = Quaternion.LookRotation(lfwd, lup);

                            hipsCurves.X.AddKey(time, rot.x);
                            hipsCurves.Y.AddKey(time, rot.y);
                            hipsCurves.Z.AddKey(time, rot.z);
                            hipsCurves.W.AddKey(time, rot.w);

                            hipsCurves.PX.AddKey(time, lpos.x);
                            hipsCurves.PY.AddKey(time, lpos.y);
                            hipsCurves.PZ.AddKey(time, lpos.z);
                        }
                    }
                }

                if (!Mathf.Approximately(time + deltaTime, clipLen))
                {
                    m_Animator.Update(deltaTime);
                    time += deltaTime;
                }
                else
                {
                    m_Animator.Update(deltaTime - 0.005f); //keep it in the range, if go beyond, something bad could happen
                    time += deltaTime - 0.005f;
                }
            }
        } //end of 1.


        { // 2. set animation clip and store in AssetDatabase
            AnimationClip newClip = new AnimationClip();
            newClip.frameRate   = SAMPLE_RATE;
            newClip.localBounds = clip.localBounds;

            // set bone curves
            for (var ie = curveDict.GetEnumerator(); ie.MoveNext();)
            {
                var curves = ie.Current.Value;
                if (ie.Current.Key == animatorTr)
                { //root motion
                    newClip.SetCurve(curves.relPath, typeof(Animator), "MotionT.x", curves.PX);
                    newClip.SetCurve(curves.relPath, typeof(Animator), "MotionT.y", curves.PY);
                    newClip.SetCurve(curves.relPath, typeof(Animator), "MotionT.z", curves.PZ);

                    newClip.SetCurve(curves.relPath, typeof(Animator), "MotionQ.x", curves.X);
                    newClip.SetCurve(curves.relPath, typeof(Animator), "MotionQ.y", curves.Y);
                    newClip.SetCurve(curves.relPath, typeof(Animator), "MotionQ.z", curves.Z);
                    newClip.SetCurve(curves.relPath, typeof(Animator), "MotionQ.w", curves.W);
                }
                else
                {
                    newClip.SetCurve(curves.relPath, typeof(Transform), "localRotation.x", curves.X);
                    newClip.SetCurve(curves.relPath, typeof(Transform), "localRotation.y", curves.Y);
                    newClip.SetCurve(curves.relPath, typeof(Transform), "localRotation.z", curves.Z);
                    newClip.SetCurve(curves.relPath, typeof(Transform), "localRotation.w", curves.W);

                    newClip.SetCurve(curves.relPath, typeof(Transform), "localPosition.x", curves.PX);
                    newClip.SetCurve(curves.relPath, typeof(Transform), "localPosition.y", curves.PY);
                    newClip.SetCurve(curves.relPath, typeof(Transform), "localPosition.z", curves.PZ);
                }
            }

            // 2.1 copy the unmapped curves to new clip( not mapped by Muscle clip )
            _CopyOtherCurves(newClip, clip);

            // some setting work
            newClip.EnsureQuaternionContinuity();

#if !U5
            AnimationUtility.SetAnimationType(newClip, m_AnimType);
            RCall.CallMtd("UnityEditor.AnimationUtility", "SetAnimationClipSettings", null, newClip, clipSetting);
#else
            if (m_AnimType == ModelImporterAnimationType.Legacy)
            {
                newClip.legacy = true;
            }
            AnimationUtility.SetAnimationClipSettings(newClip, clipSetting);
#endif

            EUtil.SaveAnimClip(newClip, newClipAssetPath);

            EUtil.ShowNotification("Converted to: " + m_AnimType +
                                   (hipsBone != null ? ("\nroot=" + AnimationUtility.CalculateTransformPath(hipsBone, animatorTr)) : ""),
                                   3f
                                   );
        } //end of 2.

        // 3. clean job
        curveDict = null;
        AssetDatabase.SaveAssets();

        Dbg.Log("Converted: {0}", newClipAssetPath);
    }