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游戏开发,如果您有更好的方法或者建议欢迎在下面给我留言,谢谢。

Unity2D研究院之自动生成动画、AnimationController、Prefab(一)的更多相关文章

  1. Unity3D研究院之Machine动画脚本自动生成AnimatorController(七十一)

    以前的项目一直不敢用Machine动画,因为当时立项的时候Machine动画还不成熟,最近项目做得差不多了我能有点时间学习,我就想在研究学习学习Machine.用Machine动画的时候需要创建一个A ...

  2. Unity3D研究院之Machine动画脚本自动生成AnimatorController

    原地址: http://www.xuanyusong.com/archives/2811 以前的项目一直不敢用Machine动画,因为当时立项的时候Machine动画还不成熟,最近项目做得差不多了我能 ...

  3. [Unity2d系列教程] 006.Unity如何根据图片自动生成Animator

    Unity制作2D产品的时候,我们在制作动画的时候,要不断的生成Animation,Animator等等资源,如果动画一多的话,就变得麻烦.由于Unity是支持插件开发的,我们可以添加一个Editor ...

  4. CoolPlist 帧动画自动生成工具

    工具英文名称:CoolPlist作者: 陈前帆 thinkingMan | sonny 邮箱: 625936034@qq.com | chenqianfan1@163.com电话: 136704713 ...

  5. .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 ...

  6. Unity3D读取模型文件自动生成AnimatorController简单实例

    前几天接到一个任务,做一个导入.控制模型动画的工具类,没有太具体的要求,于是就自行思考实际需求,最终根据宣雨松老师的一篇博客,自己规范了一下写了一个工具类.相关工具代码及测试用例已上传至Github. ...

  7. Unity自动生成AnimatorController

    上一篇写了如何自动切割动画,这一篇写如何自动生成AnimatorController. 之前网上查了很多资料,看的一直很蒙,看不懂是怎么回事的,这里我先给大家明确几个概念: 画的不好,大家将就着看,写 ...

  8. Android 自动生成的R类

    资源文件的使用分为在代码中使用和在其他资源文件中引用该资源文件.在我们编译一个Android应用时,Android会自动生成一个R类,在该类中根据不同的资源类型又生成了相应的内部类,该类包含了系统中使 ...

  9. h5自动生成工具

    一.前言 写了很多h5之后,对于写手写html和css已经麻木的我决定动手写个工具自动生成h5结构和样式.其实这个想法由来已久,但总是觉得自己技术不够,所以一直没实行.直到某天我真的写够了,我决定动手 ...

随机推荐

  1. 发送get和post请求时常用的content-type

    常见的媒体格式类型如下: text/html : HTML格式 text/plain :纯文本格式 text/xml :  XML格式 image/gif :gif图片格式 image/jpeg :j ...

  2. asp概述

    asp的理解 今天才知道,Asp原来不是一种语言,也不是一种开发工具,而是一种技术框架, 主要功能是把脚本语言,HTML,组件和Web数据库访问功能有机的结合在一起, 形成一个能在服务器端运行的应用程 ...

  3. db的操作

    '/---------------------------------------------------------------------------------------------- '/ ...

  4. OI中字符串读入和处理

    OI中字符串读入和处理 在NOIP的"大模拟"题中,往往要对字符串进行读入并处理,这些字符串有可能包含空格并以\n作为分割,传统的cin >> scanf() 等等,不 ...

  5. 关于Fragment的onActivityResult 不执行

    1.getActivity().startActivityForResult();  与 fragment.startActivityForActivity(): getActivity().star ...

  6. [NOIP2011提高组day2]-2-聪明的质监员

    2.聪明的质监员(qc.cpp/c/pas) [问题描述] 小 T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有 n 个矿石,从 1到 n 逐一编号,每个矿石都有自己的重量 wi 以及价 ...

  7. /dev/sda2 is mounted; will not make a filesystem here!

    一定要记住,不可以在分区挂载之后再进行格式化!!在错误提示当中可以看出你的分区已经挂载了.先将这个分区卸载了再重新格式化:umount /dev/sda2mkfs.ext2 /dev/sda2这样就没 ...

  8. C++类定义 常量定义

    #include "stdafx.h"#include "iostream" using namespace std; class MyClass{ int _ ...

  9. css td 溢出改为省略号

    <style> .table{ table-layout: fixed; width:100%; } .td{ width:100px; white-space: nowrap; over ...

  10. Unix高级环境编程

    [07] Unix进程环境==================================1. 进程终止    atexit()函数注册终止处理程序.    exit()或return语句:    ...