您的位置:首页 > 其它

根据图片自动生成动画

2017-06-05 10:59 85 查看
根据自己的情况 仿照 雨松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<AnimationClip> clips = new List<AnimationClip>();
foreach (DirectoryInfo ActionList in directories.GetDirectories())
{
List<AnimationClip> clipList = BuildAnimationList(ActionList);
foreach (AnimationClip clip in clipList)
{
clips.Add(clip);
}
}
AnimatorController controller = BuildAnimationController(clips, directories.Name);
BuildPrefab(directories, controller);
}

}

/// <summary>
/// Build预设
/// </summary>
/// <param name="directories"></param>
/// <param name="animatorController"></param>
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>();
_spriteRenderer.sprite = AssetDatabase.LoadAssetAtPath<Sprite>(DataPathToAssetPath(_image.FullName));

Animator _animator = _go.AddComponent<Animator>();
_animator.runtimeAnimatorController = animatorController;

System.IO.Directory.CreateDirectory(m_prefabPath);
PrefabUtility.CreatePrefab(m_prefabPath + "/" + _go.name + ".prefab", _go);
DestroyImmediate(_go);
}

/// <summary>
/// Build控制器
/// </summary>
/// <param name="clips"></param>
/// <param name="name"></param>
/// <returns></returns>
private static AnimatorController BuildAnimationController(List<AnimationClip> 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;
}

/// <summary>
/// build八个方向动画
/// </summary>
/// <param name="directories"></param>
/// <returns></returns>
private static List<AnimationClip> 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<int, List<FileInfo>> _Dic = new Dictionary<int, List<FileInfo>>();
List<AnimationClip> _dicClips = new List<AnimationClip>();
//创建方向文件夹
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<FileInfo>());
}

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(Orienta
a090
tion ori)
{
return Enum.GetName(typeof(Orientation), ori);
}

/// <summary>
/// Build动画
/// </summary>
/// <param name="fi"></param>
/// <returns></returns>
static AnimationClip BuildAnimationClip(List<FileInfo> 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<Sprite>(DataPathToAssetPath(fi[i].FullName));
//过时 Resources.LoadAssetAtPath<Sprite>(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<AnimationClip> clips = new List<AnimationClip>();
foreach (DirectoryInfo ActionList in directories.GetDirectories())
{
List<AnimationClip> clipList = BuildAnimationList(ActionList);
foreach (AnimationClip clip in clipList)
{
clips.Add(clip);
}
}
AnimatorController controller = BuildAnimationController(clips, directories.Name);
BuildPrefab(directories, controller);
}
}


这样写,只会Build选中的文件夹。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: