Unity 动画创建序列帧 代码生成AnimationClip

用Odin创建一个窗口,拖入Sprite生成AnimationClip

几个坑点:

  1. AnimationClip有个SetCurve方法可以设置曲线,AnimationCurve参数是float类型,Unity 动画创建序列帧 代码生成AnimationClip_第1张图片
    动画片段录制的是Sprite属性,没有曲线,需要创建binding;

  2. 创建EditorCurveBinding类型的binding可以设置value是Object类型的值:

    • type:动画对象身上的组件;
    • propertyName:组件上录制的参数,例如图中的Image.Sprite;获取的是私有成员"m_Sprite";
    • 获取公有成员"sprite"会Missing; 在这里插入图片描述
  3. 对动画片段编辑需用到AnimationUtility类,用SetObjectReferenceCurve设置动画曲线或ObjectReferenceKeyframe数组;

  4. 动画片段设置用AnimationClipSettings类,AnimationUtility.GetAnimationClipSettings获取,AnimationUtility.SetObjectReferenceCurve设置;

完整代码:

#if UNITY_EDITOR
using System;
using System.Collections.Generic;
using System.IO;
using DG.DemiEditor;
using UnityEditor;
using UnityEngine;
using Sirenix.OdinInspector.Editor;
using Sirenix.OdinInspector;
using Sirenix.Utilities.Editor;
using Sirenix.Utilities;
using UnityEngine.UI;

namespace Editor.Tools
{
    public class TextureTool : OdinEditorWindow
    {
        [ReadOnly] [LabelText("角色")] public string avatarName = "";
        [LabelText("每几帧一个图")] public int frame = 5;
        [LabelText("动画名称")] public string animName = "New anim";
        
        //todo 帧率设置
        // private float _frameRate = Common.FrameRate;
        private float _frameRate = 30;
        [MenuItem("Tools/Sprite2Anim")]
        private static void OpenWindow()
        {
            var window = GetWindow<TextureTool>();
            window.position = GUIHelper.GetEditorWindowRect().AlignCenter(600, 600);
            window.titleContent = new GUIContent("Create Sprite Anim");
        }
        [InlineEditor(InlineEditorModes.LargePreview)]
        [ListDrawerSettings(OnTitleBarGUI = "DrawRefreshButton")]
        [OnValueChanged("SetDefaultName")]
        public List<Sprite> sprites;

        public void SetDefaultName(List<Sprite> sprites)
        {
            if (sprites.Count == 0)
            {
                avatarName = "";
                animName = "";
                return;
            }
            string[] tmpStrs = sprites[0].name.Split(new[] {"_"}, StringSplitOptions.RemoveEmptyEntries);
            if (tmpStrs.Length <= 1) animName = tmpStrs[0];
            else
            {
                avatarName = tmpStrs[0];
                animName = tmpStrs[0] + "_" + tmpStrs[1];
            }
        }
        public void DrawRefreshButton()
        {
            if(SirenixEditorGUI.ToolbarButton(EditorIcons.Refresh))
                sprites.Clear();
        }
        
        [HorizontalGroup("Button")][Button(ButtonSizes.Gigantic, Name = "创建动画"), GUIColor(0, 1, 0)]
        public void CreateAnimationClip()
        {
            if (sprites.Count == 0)
            {
                Debug.LogError("未选中贴图");
                return;
            }

            string assetLocation = AssetUtilities.GetAssetLocation(sprites[0]);

            AnimationClip clip = new AnimationClip();
            EditorCurveBinding curveBinding = new EditorCurveBinding();
            curveBinding.type = typeof(Image);
            curveBinding.path = "";
            curveBinding.propertyName = "m_Sprite";
            ObjectReferenceKeyframe[] keyframes = new ObjectReferenceKeyframe[sprites.Count];
            for (int i = 0; i < sprites.Count; i++)
            {
                keyframes[i] = new ObjectReferenceKeyframe();
                keyframes[i].time = i * frame / _frameRate;
                keyframes[i].value = sprites[i];
            }
            
            clip.frameRate = _frameRate;
            AnimationClipSettings clipSettings = AnimationUtility.GetAnimationClipSettings(clip);
            clipSettings.loopTime = true;
            AnimationUtility.SetAnimationClipSettings(clip, clipSettings);

            AnimationUtility.SetObjectReferenceCurve(clip, curveBinding, keyframes);
            
            if (!avatarName.IsNullOrEmpty())
            {
                assetLocation += "/" + avatarName + "_anim";
                Directory.CreateDirectory(assetLocation);
            }
            
            AssetDatabase.CreateAsset(clip, assetLocation + "/" + animName + ".anim");
            AssetDatabase.SaveAssets();
        }
    }
}
#endif

你可能感兴趣的:(unity,AnimationClip,unity)