Unity2D研究院之自动生成动画、AnimationController、Prefab(一)
http://www.xuanyusong.com/archives/3243
国庆了,回家了。时刻还是要吃一颗学习的心,在家了也要抽出时间好好学习一下。之前MOMO一直没研究过Unity2D,今天研究了一下,还是把自己今天的研究笔记记录下来。现在网络上已经有很多Unity2D的技术分享了,我这篇主要说说自动生成先关的东西。
Unity2D的制作流程
1、拿到美术给的帧动画
2、打开Animation windows 手动创建动画文件
3、创建AnimationController 手动连线
4、创建Prefab文件。
这也太麻烦了。全都手动来美术每次给你好几十个动画资源那岂不是要累死程序员了。所以我们不能手动,必须自动。
如下图所示,先看看我生成出来的结果。
我们的目标是Raw文件夹下放所有美术提供的帧动画,每个文件夹就是一组帧动画,文件夹名子就是动画的名子,代码如下所示。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
using
UnityEngine;
using
System.Collections;
using
System.IO;
using
System.Collections.Generic;
using
UnityEditor;
using
UnityEditorInternal;
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("*.jpg");
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 = Resources.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.GetLayer(0);
UnityEditorInternal.StateMachine
sm = layer.stateMachine;
foreach(AnimationClip
newClip in clips)
{
State state
= sm.AddState(newClip.name);
state.SetAnimationClip(newClip,layer);
Transition
trans = sm.AddAnyStateTransition(state);
trans.RemoveCondition(0);
}
AssetDatabase.SaveAssets();
return
animatorController;
}
static
void BuildPrefab(DirectoryInfo dictorys,AnimatorController animatorCountorller)
{
//生成Prefab
添加一张预览用的Sprite
FileInfo
images = dictorys.GetDirectories()[0].GetFiles("*.jpg")[0];
GameObject
go = new GameObject();
go.name
= dictorys.Name;
SpriteRenderer
spriteRender =go.AddComponent<SpriteRenderer>();
spriteRender.sprite
= Resources.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; } }
}
}
|
因为新版的动画系统Unity没有提供直接的API来设置动画的循环状态,所以我们只能通过写文件的形式来修改动画的天生属性。需要用到自己写封装的类 AnimationClipSettings 具体方法请看上面的代码。
有了自动生成动画的代码,就不怕美术一次给你多少组图片,或者更新了多少组图片都能很快的生成出来。
随便写一条测试脚本,来测试一下播放动画。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
using
UnityEngine;
using
System.Collections;
public
class NewBehaviourScript : MonoBehaviour {
Animator
animator ;
void
Start ()
{
animator
= GetComponent<Animator>();
}
void
OnGUI()
{
if(GUILayout.Button("idle"))
{
animator.Play("idle");
}
}
}
|
动画播放的很正常的。
代码下载地址:http://pan.baidu.com/s/1eQEe3nW
欢迎大家一起讨论unity2d游戏开发,如果您有更好的方法或者建议欢迎在下面给我留言,谢谢。
- 本文固定链接: http://www.xuanyusong.com/archives/3243
- 转载请注明: 雨松MOMO 2014年10月03日 于 雨松MOMO程序研究院 发表
Unity2D研究院之自动生成动画、AnimationController、Prefab(一)的更多相关文章
- Unity3D研究院之Machine动画脚本自动生成AnimatorController(七十一)
以前的项目一直不敢用Machine动画,因为当时立项的时候Machine动画还不成熟,最近项目做得差不多了我能有点时间学习,我就想在研究学习学习Machine.用Machine动画的时候需要创建一个A ...
- Unity3D研究院之Machine动画脚本自动生成AnimatorController
原地址: http://www.xuanyusong.com/archives/2811 以前的项目一直不敢用Machine动画,因为当时立项的时候Machine动画还不成熟,最近项目做得差不多了我能 ...
- [Unity2d系列教程] 006.Unity如何根据图片自动生成Animator
Unity制作2D产品的时候,我们在制作动画的时候,要不断的生成Animation,Animator等等资源,如果动画一多的话,就变得麻烦.由于Unity是支持插件开发的,我们可以添加一个Editor ...
- CoolPlist 帧动画自动生成工具
工具英文名称:CoolPlist作者: 陈前帆 thinkingMan | sonny 邮箱: 625936034@qq.com | chenqianfan1@163.com电话: 136704713 ...
- .net mvc 站点自带简易SSL加密传输 Word报告自动生成(例如 导出数据库结构) 微信小程序:动画(Animation) SignalR 设计理念(一) ASP.NET -- WebForm -- ViewState ASP.NET -- 一般处理程序ashx 常用到的一些js方法,记录一下 CryptoJS与C#AES加解密互转
.net mvc 站点自带简易SSL加密传输 因项目需要,传输数据需要加密,因此有了一些经验,现简易抽出来分享! 请求:前端cryptojs用rsa/aes 或 rsa/des加密,后端.net ...
- Unity3D读取模型文件自动生成AnimatorController简单实例
前几天接到一个任务,做一个导入.控制模型动画的工具类,没有太具体的要求,于是就自行思考实际需求,最终根据宣雨松老师的一篇博客,自己规范了一下写了一个工具类.相关工具代码及测试用例已上传至Github. ...
- Unity自动生成AnimatorController
上一篇写了如何自动切割动画,这一篇写如何自动生成AnimatorController. 之前网上查了很多资料,看的一直很蒙,看不懂是怎么回事的,这里我先给大家明确几个概念: 画的不好,大家将就着看,写 ...
- Android 自动生成的R类
资源文件的使用分为在代码中使用和在其他资源文件中引用该资源文件.在我们编译一个Android应用时,Android会自动生成一个R类,在该类中根据不同的资源类型又生成了相应的内部类,该类包含了系统中使 ...
- h5自动生成工具
一.前言 写了很多h5之后,对于写手写html和css已经麻木的我决定动手写个工具自动生成h5结构和样式.其实这个想法由来已久,但总是觉得自己技术不够,所以一直没实行.直到某天我真的写够了,我决定动手 ...
随机推荐
- hdu 1413 文件系统
hdu 1413 文件系统 题目链接:pid=1413" target="_blank">http://acm.hdu.edu.cn/sho ...
- CI框架常识
1.有两种方法来加载自定义配置文件(如enums.php): <?php if (! defined('BASEPATH')) exit('No direct script access all ...
- Android-运行时权限
由于拨打电话数据用户的隐私,再者由于在5.0之后Android更注重于用户的隐私权限,为此出现了在低版本没有的问题,而在高版本出现的个别问题! Intent intent = new Intent(I ...
- quick-cocos2d-x教程3:程序框架内文件夹分析之docs文件夹
如今我们分析框架中的docs文件夹.看看这个文档文件夹中,究竟放了那些对我们实用的东西. docs文件夹分析 UPGRADE_TO_2_2_3.md 就是讲升级的变化.详细说明:quick-cocos ...
- MySQL 存储过程 (3)
以下介绍下像数据库循环插入数据操作 第一步:建立存储过程用到的信息表
- EasyDarwin开源流媒体服务器低延时直播之转发缓存跟进算法
前言 前一段时间,我们为EasyDarwin实现了客户端快速显示画面/听到同步声音的缓存关键帧检索方案,具体的实现方法分别在<EasyDarwin手机直播是如何实现的快速显示视频的方法>和 ...
- linux系统上安装svn服务器 环境linux+nginx+svnserver
系统:Ubuntu 12.04 64位 lnmp环境 集成软件:PHP5.4.27.Nginx1.6.0.MySQL5.5.37 阿里云server svnserver有2种执行方式:独立server ...
- CSS3学习笔记(4)—上下滑动展开的按钮
最近写了一个动画,下面来看看我以前写的一个上下滑动展开的按钮效果: 这类的效果经常会在一些网站页面下载按钮处看到,当你鼠标悬浮在下载按钮时,会提醒你是否已注册,或者点击登录什么的小提示~~~~~ 一. ...
- NYOJ-37 回文字符串 —— LCS变形
题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=37 题解: 一开始想从两边向中间添加字符,发现这样不是最优的.因为加入字符之后,这些原本存 ...
- 图片预览JavaScript方法
实现要点 ● 对于 Chrome.Firefox.IE10 使用 FileReader 来实现. ● 对于 IE6~9 使用滤镜 filter:progid:DXImageTransform.Mi ...