根据自己的情况 仿照 雨松MOMO 写了一个自动生成动画的脚本 原地址 http://www.xuanyusong.com/archives/3243
代码:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using System;
using System.IO;
using UnityEditor.Animations;
public enum Orientation
{
Down = 1, RightDown, Right, RightUp, Up, LeftUp, Left, LeftDown
}
public class BuildAnimation : Editor
{
#region 常量
#endregion
#region 事件
#endregion
#region 字段
private static string m_prefabPath = "Assets/Resources/Prefabs";
private static string m_AnimationControllerPath = "Assets/AnimationController";
private static string m_animationPath = "Assets/Animation";
private static string m_rawImagePath = Application.dataPath + "/Raw";
#endregion
#region 属性
#endregion
#region 方法
[MenuItem("Assets/BuildAnimation")]
static void BuildAnimations() {
DirectoryInfo raw = new DirectoryInfo(m_rawImagePath);
foreach (DirectoryInfo directories in raw.GetDirectories())
{
List clips = new List();
foreach (DirectoryInfo ActionList in directories.GetDirectories())
{
List clipList = BuildAnimationList(ActionList);
foreach (AnimationClip clip in clipList)
{
clips.Add(clip);
}
}
AnimatorController controller = BuildAnimationController(clips, directories.Name);
BuildPrefab(directories, controller);
}
}
///
/// Build预设
///
///
///
private static void BuildPrefab(DirectoryInfo directories, AnimatorController animatorController)
{
FileInfo _image = directories.GetDirectories()[0].GetFiles("*.png")[0];
GameObject _go = new GameObject();
_go.name = directories.Name;
SpriteRenderer _spriteRenderer = _go.AddComponent();
_spriteRenderer.sprite = AssetDatabase.LoadAssetAtPath(DataPathToAssetPath(_image.FullName));
Animator _animator = _go.AddComponent();
_animator.runtimeAnimatorController = animatorController;
System.IO.Directory.CreateDirectory(m_prefabPath);
PrefabUtility.CreatePrefab(m_prefabPath + "/" + _go.name + ".prefab", _go);
DestroyImmediate(_go);
}
///
/// Build控制器
///
///
///
///
private static AnimatorController BuildAnimationController(List clips, string name)
{
//string _parentName = System.IO.Directory.GetParent(directories.FullName).Name;
//创建文件夹
System.IO.Directory.CreateDirectory(m_AnimationControllerPath);
AnimatorController animatorController = AnimatorController.
CreateAnimatorControllerAtPath(m_AnimationControllerPath + "/" + name + ".controller");
AnimatorControllerLayer layer = animatorController.layers[0];
AnimatorStateMachine sm = layer.stateMachine;
foreach (AnimationClip newClip in clips)
{
AnimatorState state = sm.AddState(newClip.name);
state.motion = newClip;
//设置默认状态
if (state.name == "idle_Down")
{
sm.defaultState = state;
}
//_state.SetAnimationClip(newClip, _layer);
//AnimatorStateTransition trans = sm.AddAnyStateTransition(_state);
//trans.RemoveCondition(0);
}
AssetDatabase.SaveAssets();
return animatorController;
}
///
/// build八个方向动画
///
///
///
private static List BuildAnimationList(DirectoryInfo directories)
{
string _animationName = directories.Name;
FileInfo[] _images = directories.GetFiles("*.png");
//创建unit文件夹
string _parentName = System.IO.Directory.GetParent(directories.FullName).Name;
System.IO.Directory.CreateDirectory(m_animationPath + "/" + _parentName);
Dictionary> _Dic = new Dictionary>();
List _dicClips = new List();
//创建方向文件夹
for (int i = 1; i < 9; i++)
{
string _enumName = EnumToString((Orientation)i);
System.IO.Directory.CreateDirectory(m_animationPath + "/" + _parentName + "/" + _enumName);
_Dic.Add(i, new List());
}
for (int i = 0; i < _images.Length; i++)
{
//获取无扩展名的文件名
string _fileName = Path.GetFileNameWithoutExtension(_images[i].ToString());
int initial = (int)(_fileName[0]);
//根据首字母添加
// Debug.Log(_fileName[0]);
// Debug.Log(initial);
_Dic[initial - 48].Add(_images[i]);
}
foreach (int key in _Dic.Keys)
{
AnimationClip _clip = new AnimationClip();
_clip = BuildAnimationClip(_Dic[key]);
//动画循环
if (_animationName.IndexOf("idle") >= 0)
{
//设置idle文件为循环动画
SerializedObject serializedClip = new SerializedObject(_clip);
AnimationClipSetting clipSettings = new AnimationClipSetting(serializedClip.FindProperty("m_AnimationClipSettings"));
clipSettings.loopTime = true;
serializedClip.ApplyModifiedProperties();
}
string _enumName = EnumToString((Orientation)key);
System.IO.Directory.CreateDirectory(m_animationPath + "/" + _parentName + "/" + _enumName);
AssetDatabase.CreateAsset(_clip, m_animationPath + "/" + _parentName
+ "/" + _enumName + "/" + _animationName + "_" + _enumName + ".anim");
_dicClips.Add(_clip);
}
return _dicClips;
}
static string EnumToString(Orientation ori)
{
return Enum.GetName(typeof(Orientation), ori);
}
///
/// Build动画
///
///
///
static AnimationClip BuildAnimationClip(List fi) {
AnimationClip _clipTemp = new AnimationClip();
_clipTemp.frameRate = 30;
//AnimationUtility.SetAnimationType(_clipTemp, ModelImporterAnimationType.Generic);
EditorCurveBinding _curveBinding = new EditorCurveBinding();
_curveBinding.type = typeof(SpriteRenderer);
_curveBinding.path = "";
_curveBinding.propertyName = "m_Sprite";
ObjectReferenceKeyframe[] _keyFrames = new ObjectReferenceKeyframe[fi.Count];
float _frameTime = 1 / 10f;
for (int i = 0; i < _keyFrames.Length; i++)
{
Sprite _sprite = AssetDatabase.LoadAssetAtPath(DataPathToAssetPath(fi[i].FullName));
//过时 Resources.LoadAssetAtPath(DataPathToAssetPath(_images[i].FullName));
_keyFrames[i] = new ObjectReferenceKeyframe();
_keyFrames[i].time = _frameTime * i;
_keyFrames[i].value = _sprite;
}
AnimationUtility.SetObjectReferenceCurve(_clipTemp, _curveBinding, _keyFrames);
AssetDatabase.SaveAssets();
return _clipTemp;
}
private static string DataPathToAssetPath(string path)
{
if (Application.platform == RuntimePlatform.WindowsEditor)
{
return path.Substring(path.IndexOf("Assets\\"));
}
else {
return path.Substring(path.IndexOf("Assets/"));
}
}
#endregion
#region Unity回调
#endregion
#region 事件回调
#endregion
#region 帮助方法
#endregion
}
class AnimationClipSetting
{
private SerializedProperty m_Property;
private SerializedProperty Get(string property)
{
return m_Property.FindPropertyRelative(property);
}
public AnimationClipSetting(SerializedProperty prop)
{
this.m_Property = prop;
}
public float startTime {
get { return Get("m_StartTime").floatValue; }
set { Get("m_StartTime").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; }
}
}
这样做有个问题,每一次点击BuildAnimation都会重新加载所有资源,如果数据量大的话,更新会很不方便。
有以下修改:
[MenuItem("Assets/BuildAnimation")]
static void BuildAnimations()
{
//选中的文件夹,不包括子文件夹
UnityEngine.Object[] filter = Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.TopLevel);
//路径中包含"Raw" 或者选中的是"Raw"
if (!AssetDatabase.GetAssetPath(filter[0]).Contains("Raw") || Path.GetFileNameWithoutExtension(AssetDatabase.GetAssetPath(filter[0])) == "Raw")
{
Debug.LogError("没有选中对的文件夹");
return;
}
DirectoryInfo[] filterInfo = new DirectoryInfo[filter.Length];
for (int i = 0; i < filter.Length; i++)
{
filterInfo[i] = new DirectoryInfo(Application.dataPath.Substring(0,Application.dataPath.LastIndexOf("/")) + "/" + AssetDatabase.GetAssetPath(filter[i]));
}
foreach (DirectoryInfo directories in filterInfo)
{
List clips = new List();
foreach (DirectoryInfo ActionList in directories.GetDirectories())
{
List clipList = BuildAnimationList(ActionList);
foreach (AnimationClip clip in clipList)
{
clips.Add(clip);
}
}
AnimatorController controller = BuildAnimationController(clips, directories.Name);
BuildPrefab(directories, controller);
}
}
这样写,只会Build选中的文件夹。