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 ...
- RS485总线典型电路介绍
一.RS485总线介绍: RS485总线是一种常见的串行总线标准,采用平衡发送与差分接收的方式,因此具有抑制共模干扰的能力.在一些要求通信距离为几十米到上千米的时候,RS485总线是一种应用最为广泛的 ...
- EasyPusher:基于live555的DarwinInjector实现的RTSP直播推送程序
先简单介绍一下EasyPusher的功能,后面再对具体内部架构做介绍: EasyPusher:https://github.com/EasyDarwin/EasyPusher EasyPusher是什 ...
- ABAP DEMO-2018
sap Program DEMO 介绍 Program Description BALVBT01 Example SAP program for displying multiple ALV repo ...
- nyoj 269 VF
VF 时间限制:1000 ms | 内存限制:65535 KB 链接:NYOJ269 原创在:点击打开链接 题意:1-1000000000之间,各位数字之和等于给定s的数的个数. 每行给出一个数s ...
- codeforces 701E E. Connecting Universities(树的重心)
题目链接: E. Connecting Universities time limit per test 3 seconds memory limit per test 256 megabytes i ...
- 让Spinner中的文字居中
如果套用simple_spinner_item或是simple_spinner_dropdown_item,然后直接在Spinner中用 android:gravity="center&qu ...
- HBase之四--(3):hbasehbase分页查询
为了广大技术爱好者学习netty,在这里帮新浪微博@nettying宣传下他出版的新书 <netty权威指南>@nettying兄在华为NIO实践多年,这本书是他的技术和经验的一个结晶.N ...
- leetcode 395 至少有K个重复字符的最长子串
找到给定字符串(由小写字符组成)中的最长子串 T , 要求 T 中的每一字符出现次数都不少于 k .输出 T 的长度. 示例 1: 输入: s = "aaabb", k = 3 输 ...
- zlog日志库的简单封装,以及给debug级别添加颜色显示
现看看效果如何: 方法如下: 定义相关颜色的宏 #define ESC_START "\033[" #define ESC_END "\033[0m" #def ...