[Unity2d系列教程] 006.Unity如何根据图片自动生成Animator
Unity制作2D产品的时候,我们在制作动画的时候,要不断的生成Animation,Animator等等资源,如果动画一多的话,就变得麻烦。由于Unity是支持插件开发的,我们可以添加一个Editor,然后把美术的动画图片放在指定的位置。
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEditor.Animations; public class BuildAnimation : Editor
{ //生成出的Prefab的路径
private static string PrefabPath = "Assets/Resources/Prefabs";
//生成出的AnimationController的路径
private static string AnimationControllerPath = "Assets/AnimationController";
//生成出的Animation的路径
private static string AnimationPath = "Assets/Animation";
//美术给的原始图片路径
private static string ImagePath = Application.dataPath +"/Raw"; [MenuItem("Build/BuildAnimaiton")]
static void BuildAniamtion()
{
DirectoryInfo raw = new DirectoryInfo (ImagePath);
foreach (DirectoryInfo dictorys in raw.GetDirectories())
{
List<AnimationClip> clips = new List<AnimationClip>();
foreach (DirectoryInfo dictoryAnimations in dictorys.GetDirectories())
{
//每个文件夹就是一组帧动画,这里把每个文件夹下的所有图片生成出一个动画文件
clips.Add(BuildAnimationClip(dictoryAnimations));
}
//把所有的动画文件生成在一个AnimationController里
AnimatorController controller = BuildAnimationController(clips,dictorys.Name);
//最后生成程序用的Prefab文件
BuildPrefab(dictorys,controller);
}
} static AnimationClip BuildAnimationClip(DirectoryInfo dictorys)
{
string animationName = dictorys.Name;
//查找所有图片,因为我找的测试动画是.jpg
FileInfo []images = dictorys.GetFiles("*.png");
AnimationClip clip = new AnimationClip();
//AnimationUtility.SetAnimationType(clip,ModelImporterAnimationType.Generic);
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++){
Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>(DataPathToAssetPath(images[i].FullName));
keyFrames[i] = new ObjectReferenceKeyframe ();
keyFrames[i].time = frameTime *i;
keyFrames[i].value = sprite;
}
//动画帧率,30比较合适
clip.frameRate = 30; //有些动画我希望天生它就动画循环
if(animationName.IndexOf("idle") >=0 )
{
//设置idle文件为循环动画
SerializedObject serializedClip = new SerializedObject(clip);
AnimationClipSettings clipSettings = new AnimationClipSettings(serializedClip.FindProperty("m_AnimationClipSettings"));
clipSettings.loopTime = true;
serializedClip.ApplyModifiedProperties();
}
string parentName = System.IO.Directory.GetParent(dictorys.FullName).Name;
System.IO.Directory.CreateDirectory(AnimationPath +"/"+parentName);
AnimationUtility.SetObjectReferenceCurve(clip,curveBinding,keyFrames);
AssetDatabase.CreateAsset(clip,AnimationPath +"/"+parentName +"/" +animationName+".anim");
AssetDatabase.SaveAssets();
return clip;
} static AnimatorController BuildAnimationController(List<AnimationClip> clips ,string name)
{
AnimatorController animatorController = AnimatorController.CreateAnimatorControllerAtPath(AnimationControllerPath +"/"+name+".controller");
AnimatorControllerLayer layer = animatorController.layers[0];
AnimatorStateMachine sm = layer.stateMachine;
foreach(AnimationClip newClip in clips)
{
//AnimatorStateMachine machine = sm.AddStateMachine(newClip.name);
AnimatorState state = sm.AddState(newClip.name);
state.motion = newClip;
//AnimatorStateTransition trans = sm.AddAnyStateTransition(state);
if(newClip.name == "idle"){
sm.defaultState = state;
}
//sm.AddEntryTransition(machine);
//sm.AddStateMachineExitTransition(machine);
//trans.RemoveCondition(0);
}
AssetDatabase.SaveAssets();
return animatorController;
} 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;
SpriteRenderer spriteRender =go.AddComponent<SpriteRenderer>();
spriteRender.sprite = AssetDatabase.LoadAssetAtPath<Sprite>(DataPathToAssetPath(images.FullName));
Animator animator = go.AddComponent<Animator>();
animator.runtimeAnimatorController = animatorCountorller;
PrefabUtility.CreatePrefab(PrefabPath+"/"+go.name+".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/"));
} class AnimationClipSettings
{
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; } }
} }
以上代码支持Unity5.0以上。
代码拷贝进去自己试试就知道了,非常方便
[Unity2d系列教程] 006.Unity如何根据图片自动生成Animator的更多相关文章
- [Unity2d系列教程] 003.Unity如何调用android的方法
Unity开发的时候很多时候我们需要用到底层的一些功能,比如摄像,录音,震动等等,我们在Unity的层面是无法完成的.那么我们考虑到Unity是否可以直接调用到android方面的方法,替我们去完成我 ...
- [Unity2d系列教程] 005.Unity如何使用外部触控插件FingerGuesture
用过Unity的都知道自带的Input.touches并不支持鼠标输入,给我们的调试带来很大的不方便.那么我们会发现其实有很多触控方面的插件,如inputtouches,easy touch,fing ...
- [Unity2d系列教程] 004.Unity如何调用ios的方法(SDK集成相关)
和上一篇类似,我们同样希望Unity能够直接调用IOS底层的代码,那么我们就需要研究怎么去实现它.下面让我来带大家看一个简单的例子 1.创建.h和.m文件如下 .h // // myTest.m // ...
- 黄聪:Microsoft Enterprise Library 5.0 系列教程(八) Unity Dependency Injection and Interception
原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(八) Unity Dependency Injection and Interception 依赖注入容器Uni ...
- Springboot 系列(十一)使用 Mybatis(自动生成插件) 访问数据库
1. Springboot mybatis 介绍 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数获取 ...
- [Unity2d系列教程] 002.引用外部DLL - C
上一篇我们学习了Unity调用C#生成的外部DLL,但是有时候我们需要访问底层,不能不适用C生成的DLL.下面就让我们一起学习下,C如何生成. 1.创建一个C的控制台程序 2.点击确定->点击下 ...
- [Unity2d系列教程] 001.引用外部DLL - C#
众所周知,Unity可以支持多种语言开发, C#, JS, Boo三种方式的开发, 能够很方便的集成一些外部插件,以便调用现有的动态链接库.学过C#的都知道C#可以生成一个dll供给其他的程序调用.那 ...
- 【前端】CentOS 7 系列教程之四: 配置 git 服务器自动部署
转载请注明出处:http://www.cnblogs.com/shamoyuu/p/linux_4.html 安装pm2守护进程,备用 npm install -g pm2 创建/srv/www文件夹 ...
- TensorFlow从1到2(十二)生成对抗网络GAN和图片自动生成
生成对抗网络的概念 上一篇中介绍的VAE自动编码器具备了一定程度的创造特征,能够"无中生有"的由一组随机数向量生成手写字符的图片. 这个"创造能力"我们在模型中 ...
随机推荐
- RobotFrameWork 自动化环境搭建(基于 python2.7)
1.自动化工具安装顺序 robot Framework(两个RF框架) WXpython(不要更改安装路径,自动安装在python文件中) 安装依赖库 RF3.0 和 RF1.5.2.1 打开 rid ...
- zabbix 数据库分区表配置
下载 pwd /usr/local/zabbix/share/zabbix/externalscriptswget http://cactifans.hi-www.com/zabbix/partiti ...
- 如何使用Golang实现一个API网关
你是否也存在过这样的需求,想要公开一个接口到网络上.但是还得加点权限,否则被人乱调用就不好了.这个权限验证的过程,最好越简单越好,可能只是对比两个字符串相等就够了.一般情况下我们遇到这种需要,就是在函 ...
- 设计模式(Java语言)- 建造者模式
前言 在日常的生活中,我们可以经常看到建造者模式的影子.比如,建造房子,那么房子就是一个产品,房子由门,窗,墙,地板等部门组成.然后包工头在建造房子的时候就根据设计好的图纸来建造,但是包工头并不是亲自 ...
- oracle如何实现去重和分页
一:oracle实现去重: user数据表: 分两步:1.查询重复数据 2.删除重复数据 1.查询重复数据:在oracle中实现查询重复数据,可以借助于rowid这个伪列.oracle中每个表物理上 ...
- matlab数值数据和变量名
1.2MATLAB数值数据 l 数值数据类型的分类 l 数值数据的输出格式 l 常用数学函数内部函数 1.数值数据类型的分类 l 整型 l 浮点型 l 复数型 (1)整型 1.数值数据类型 ...
- LTE网络概述
LTE主要由两部分组成:无线接入技术演进(E-UTRAN)+系统架构演进(SAE):其中,SAE主要含有的是演进型分组交换核心网(EPC),其控制处理部分为移动性管理实体(MME),数据承载部分称为业 ...
- 一篇博客带你轻松应对java面试中的多线程与高并发
1. Java线程的创建方式 (1)继承thread类 thread类本质是实现了runnable接口的一个实例,代表线程的一个实例.启动线程的方式start方法.start是一个本地方法,执行后,执 ...
- BOM基础
BOM基础 打开窗口 window.open('about:blank','_blank') 第一个参数是打开哪一个口,第二个参数是在哪里打开窗口. 关闭窗口 window.close() windo ...
- Android 8.1 关机充电动画(二)Uboot模式
system:Android 8.1 platform:RK3326/PX30 uboot kernel Android 8.1 关机充电动画(一)模式选择 Android 8.1 关机充电动画(二) ...