using UnityEngine;
using System.Collections;
using UnityEditor;
using System.IO;
using System.Collections.Generic;
using U3d.Wj.Common;
using UnityEditor.Animations;
/// <summary>
/// Animation prefab creator.
/// Aurthor : Wang
/// Date : 20160608
/// Version : Unity 5.2.2
/// PS : 大部分代码都借鉴了雨松http://www.xuanyusong.com/archives/3243的文章
/// 并根据需求以及API的更新修改了部分代码
/// 实现功能为美工提供每个人物的所有动画序列帧 用此脚本直接生成预制体
/// </summary>
public class AnimPrefabCreator {
#if UNITY_EDITOR
class Generator
{
private static string ImagesPath = Application.dataPath + "/Resources/KingDomRush";
private static string AnimationPath = "Assets/Animation";
private static string AnimationControllerPath = "Assets/AnimationController";
private static string PrefabPath = "Assets/Resources/Prefabs";
[MenuItem("Edit/将所有序列帧生成预制体")]
private static void CreateAnimation()
{
DirectoryInfo baseDictory = new DirectoryInfo(ImagesPath);
// 获取所有人物分类文件夹
foreach (DirectoryInfo dictorys in baseDictory.GetDirectories()) {
List<AnimationClip> clips = new List<AnimationClip>();
// 获取每个人物的所有动作分类文件夹 把每组帧动画生成一个动画文件
foreach (DirectoryInfo dictoryAnimations in dictorys.GetDirectories()) {
AnimationClip clip = BuildAnimationClip(dictoryAnimations);
if(clip == null) continue;
clips.Add(clip);
}
// 将每个人物的所有动画文件生成在一个AnimationController里
AnimatorController controller = BuildAnimationController(clips,dictorys.Name.StrToPinyin());
// 最后生成程序用的prefab文件
BuildPrefab(dictorys,controller);
}
}
static void BuildPrefab(DirectoryInfo dictorys,AnimatorController animatorCountorller)
{
//生成Prefab 添加一张预览用的Sprite
FileInfo images = dictorys.GetDirectories()[0].GetFiles("*.png")[0];
GameObject go = new GameObject();
go.name = dictorys.Name.StrToPinyin();
SpriteRenderer spriteRender =go.AddComponent<SpriteRenderer>();
string imgPath = images.FullName.Replace("\\","/");
imgPath = imgPath.Substring(imgPath.IndexOf("KingDomRush/"));
// 移除".png"后缀名
imgPath = imgPath.Remove(imgPath.Length - 4,4);
spriteRender.sprite = Resources.Load<Sprite>(imgPath);
Animator animator = go.AddComponent<Animator>();
animator.runtimeAnimatorController = animatorCountorller;
PrefabUtility.CreatePrefab(PrefabPath+"/"+go.name+".prefab",go);
GameObject.DestroyImmediate(go);
}
private static AnimatorController BuildAnimationController(List<AnimationClip> clips,string controllerName)
{
AnimatorController animController = AnimatorController.CreateAnimatorControllerAtPath(AnimationControllerPath + "/" + controllerName + ".controller");
AnimatorControllerLayer layer = animController.layers[0];
AnimatorStateMachine sm = layer.stateMachine;
foreach (AnimationClip newClip in clips) {
// 将动画名字取出 放入state状态机里
AnimatorState state = sm.AddState(newClip.name);
state.motion = newClip;
AnimatorStateTransition transition = sm.AddAnyStateTransition(state);
// 移除默认时间条件
//transition.RemoveCondition(transition.conditions[0]);
}
AssetDatabase.SaveAssets();
return animController;
}
// 传值入一个目录文件夹 生成一个序列帧动画
private static AnimationClip BuildAnimationClip(DirectoryInfo dictorys)
{
string animationName = dictorys.Name;
// 查找所有png类型图片
FileInfo[] images = dictorys.GetFiles("*.png");
if(images.Length == 0) return null;
AnimationClip clip = new AnimationClip();
//AnimationClipSettings setting = new AnimationClipSettings();
//AnimationUtility.SetAnimationClipSettings(clip,setting);
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++)
{
string imgPath = images[i].FullName.Substring(images[i].FullName.IndexOf("KingDomRush\\"));
imgPath = imgPath.Replace("\\","/");
NormalizeTextureType(DataPathToAssetsPath(imgPath));
imgPath = imgPath.Remove(imgPath.Length - 4,4);
Sprite sprite = Resources.Load<Sprite>(imgPath);
keyFrames[i] = new ObjectReferenceKeyframe();
keyFrames[i].time = frameTime * i;
keyFrames[i].value = sprite;
}
// 动画帧率
clip.frameRate = 30;
// 需要设置循环的动画
if (animationName.Equals("attack") || animationName.Equals("run-right"))
{
AnimationClipSettings setting = new AnimationClipSettings();
setting.loopTime = true;
AnimationUtility.SetAnimationClipSettings(clip,setting);
}
string parentName = Directory.GetParent(dictorys.FullName).Name;
Directory.CreateDirectory(AnimationPath + "/" + parentName.StrToPinyin());
AnimationUtility.SetObjectReferenceCurve(clip,curveBinding,keyFrames);
AssetDatabase.CreateAsset(clip,AnimationPath + "/" + parentName.StrToPinyin() + "/" + animationName + ".anim");
AssetDatabase.SaveAssets();
return clip;
}
static void NormalizeTextureType(string path)
{
TextureImporter textureImporter = AssetImporter.GetAtPath(path)as TextureImporter;
textureImporter.textureType = TextureImporterType.Sprite;
TextureImporterSettings settings = new TextureImporterSettings();
textureImporter.ReadTextureSettings(settings);
textureImporter.SetTextureSettings(settings);
AssetDatabase.ImportAsset(path);
}
// 例 abc.png
// return "Assets/Resources/abc.png";
static string DataPathToAssetsPath(string fullPath)
{
fullPath = "Assets/Resources/" + fullPath;
return fullPath;
}
}
#endif
}
using U3d.Wj.Common;
是主程给我提供的命名空间。主要用到了里面的将中文文件夹名转换成拼音的API(.StrToPinyin());