仿照 雨松MOMO 写了一个自动生成动画的脚本 原地址 http://www.xuanyusong.com/archives/3243
添加菜单Tools/CreateAnimation,弹出窗口
你需要设置动画名、是否循环及动画播放帧率,拖入一张待生成动画的图片。
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.UI;
using System.IO;
using UnityEditor.Animations;
public class CreateAnimation : EditorWindow {
string AnimationName = "";
Texture2D ImageName;
//图片所在文件夹位置
string ImagePath = "";
//动画存放位置
string AnimationPath = "";
//预制体存放位置
string PrefabPath = "";
//动画是否循环
bool showBtn = true;
//动画帧率
string frameRate = "";
//定义弹出当前窗口的菜单位置
[MenuItem("Tools/CreateAnimation")]
static void Init()
{
//弹出窗口
EditorWindow.GetWindow(typeof(CreateAnimation));
}
void OnGUI()
{
AnimationName = EditorGUILayout.TextField("待生成的动画名:", AnimationName);
EditorGUILayout.BeginHorizontal();
ImageName = (Texture2D)EditorGUILayout.ObjectField("待用第一张图片:", ImageName, typeof(Texture2D));
EditorGUILayout.EndHorizontal();
showBtn = EditorGUILayout.Toggle("是否循环", showBtn);
frameRate = EditorGUILayout.TextField("动画帧率(默认30):", frameRate);
ImagePath = EditorGUILayout.TextField("图片获取路径:", ImagePath);
AnimationPath = EditorGUILayout.TextField("动画生成位置:", AnimationPath);
PrefabPath = EditorGUILayout.TextField("预制体生成位置:", PrefabPath);
if (GUI.Button(new Rect(Screen.width / 4, 200, Screen.width / 2, 30), "生成动画"))
{
BuildAnimation();
}
}
void BuildAnimation()
{
if (AnimationName == "" || ImageName == null)
{
Debug.LogError("没有给动画命名或没有选入图片");
return;
}
if (ImagePath != null)
{
ImagePath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(ImageName));
string[] _tempPath = Path.GetDirectoryName(ImagePath).Split('/');
string ss = "";
AnimationPath = _tempPath[0] + "/Animation";
PrefabPath = _tempPath[0] + "/Resources/Prefabs";
for (int i = 2; i < _tempPath.Length; i++)
{
ss += ("/" + _tempPath[i]);
}
AnimationPath += (ss + "/" + _tempPath[_tempPath.Length - 1] + "_anim");
PrefabPath += (ss + "/" + _tempPath[_tempPath.Length - 1] + "_Prefab");
//创建文件夹
Directory.CreateDirectory(AnimationPath);
Directory.CreateDirectory(PrefabPath);
}
DirectoryInfo info = new DirectoryInfo(Application.dataPath.Substring(0, Application.dataPath.LastIndexOf("/")) + "/" + ImagePath);
//Debug.Log(info);
List<AnimationClip> clips = new List<AnimationClip>();
clips.Add(BuildAnimationClip(info));
AnimatorController controller = BuildAnimationController(clips);
BuildPrefab(info, controller);
}
AnimationClip BuildAnimationClip(DirectoryInfo dictorys)
{
string animationName = dictorys.Name;
List<FileInfo> images = new List<FileInfo>();
foreach (FileInfo fi in dictorys.GetFiles())
{
if (fi.Extension.Equals(".png") && !fi.Extension.Equals(".meta"))
{
images.Add(fi);
}
}
AnimationClip clip = new AnimationClip();
EditorCurveBinding curveBinding = new EditorCurveBinding();
curveBinding.type = typeof(Image);
curveBinding.path = "";
curveBinding.propertyName = "m_Sprite";
ObjectReferenceKeyframe[] keyFrames = new ObjectReferenceKeyframe[images.Count];
float frameTime = 1 / 10f;
for (int i = 0; i < images.Count; i++)
{
Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>(DataPathToAssetPath(images[i].FullName));
keyFrames[i] = new ObjectReferenceKeyframe();
keyFrames[i].time = frameTime * i;
keyFrames[i].value = sprite;
}
if (frameRate == "")
{
clip.frameRate = 30;
frameRate = "30";
}
else
{
clip.frameRate = int.Parse(frameRate);
}
if (showBtn)
{
SerializedObject serializedClip = new SerializedObject(clip);
AnimationClipSettings clipSettings = new AnimationClipSettings(serializedClip.FindProperty("m_AnimationClipSettings"));
clipSettings.loopTime = true;
serializedClip.ApplyModifiedProperties();
}
AnimationUtility.SetObjectReferenceCurve(clip, curveBinding, keyFrames);
AssetDatabase.CreateAsset(clip, AnimationPath + "/" + AnimationName + ".anim");
AssetDatabase.SaveAssets();
return clip;
}
AnimatorController BuildAnimationController(List<AnimationClip> clips)
{
AnimatorController animatorController = AnimatorController.CreateAnimatorControllerAtPath(AnimationPath + "/" + AnimationName + ".controller");
AnimatorControllerLayer layer = animatorController.layers[0];
AnimatorStateMachine sm = layer.stateMachine;
foreach (AnimationClip newClip in clips)
{
AnimatorState state = sm.AddState(newClip.name);
state.motion = newClip;
}
AssetDatabase.SaveAssets();
return animatorController;
}
void BuildPrefab(DirectoryInfo dictorys, AnimatorController animatorCountorller)
{
FileInfo images = dictorys.GetFiles("*.png")[0];
GameObject go = new GameObject();
go.name = AnimationName;
Image img = go.AddComponent<Image>();
go.GetComponent<RectTransform>().sizeDelta = new Vector2(ImageName.width, ImageName.height);
img.sprite = AssetDatabase.LoadAssetAtPath<Sprite>(DataPathToAssetPath(images.FullName));
Animator animator = go.AddComponent<Animator>();
animator.runtimeAnimatorController = animatorCountorller;
PrefabUtility.CreatePrefab(PrefabPath +"/" + AnimationName + ".prefab", go);
DestroyImmediate(go);
}
public static string DataPathToAssetPath(string path)
{
if (Application.platform == RuntimePlatform.WindowsEditor)
return path.Substring(path.IndexOf("Assets\\"));
else
return path.Substring(path.IndexOf("Assets/"));
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public class AnimationClipSettings : Editor
{
SerializedProperty m_Property;
private SerializedProperty Get(string property) { return m_Property.FindPropertyRelative(property); }
public AnimationClipSettings(SerializedProperty prop) { m_Property = prop; }
public float startTime { get { return Get("m_StartTime").floatValue; } set { Get("m_StartTime").floatValue = value; } }
public float stopTime { get { return Get("m_StopTime").floatValue; } set { Get("m_StopTime").floatValue = value; } }
public float orientationOffsetY { get { return Get("m_OrientationOffsetY").floatValue; } set { Get("m_OrientationOffsetY").floatValue = value; } }
public float level { get { return Get("m_Level").floatValue; } set { Get("m_Level").floatValue = value; } }
public float cycleOffset { get { return Get("m_CycleOffset").floatValue; } set { Get("m_CycleOffset").floatValue = value; } }
public bool loopTime { get { return Get("m_LoopTime").boolValue; } set { Get("m_LoopTime").boolValue = value; } }
public bool loopBlend { get { return Get("m_LoopBlend").boolValue; } set { Get("m_LoopBlend").boolValue = value; } }
public bool loopBlendOrientation { get { return Get("m_LoopBlendOrientation").boolValue; } set { Get("m_LoopBlendOrientation").boolValue = value; } }
public bool loopBlendPositionY { get { return Get("m_LoopBlendPositionY").boolValue; } set { Get("m_LoopBlendPositionY").boolValue = value; } }
public bool loopBlendPositionXZ { get { return Get("m_LoopBlendPositionXZ").boolValue; } set { Get("m_LoopBlendPositionXZ").boolValue = value; } }
public bool keepOriginalOrientation { get { return Get("m_KeepOriginalOrientation").boolValue; } set { Get("m_KeepOriginalOrientation").boolValue = value; } }
public bool keepOriginalPositionY { get { return Get("m_KeepOriginalPositionY").boolValue; } set { Get("m_KeepOriginalPositionY").boolValue = value; } }
public bool keepOriginalPositionXZ { get { return Get("m_KeepOriginalPositionXZ").boolValue; } set { Get("m_KeepOriginalPositionXZ").boolValue = value; } }
public bool heightFromFeet { get { return Get("m_HeightFromFeet").boolValue; } set { Get("m_HeightFromFeet").boolValue = value; } }
public bool mirror { get { return Get("m_Mirror").boolValue; } set { Get("m_Mirror").boolValue = value; } }
}