第一部分:介绍


AnimationCurve是Unity3D里一个非常实用的功能。作用是编辑一条任意变化的曲线用在任何你想用在的地方。如曲线地形,曲线轨迹等。也被用在了模型动画播放时的碰撞盒缩放及重力调节。AnimationCurve 曲线的绘制方法和Ragespline中的物体轮廓勾勒的方法类似。



第二部分:基本使用


第一步:创建物体


第二步:创建脚本


创建AnimationCurveTutor.cs的脚本并添加到物体上。代码如下。

1. using UnityEngine; 
2. using System.Collections; 
3. public class AnimationCurveTutor : MonoBehaviour { 
4. public AnimationCurve anim; 
5. }


第三步:绘制曲线


把脚本添加到物体上后,物体的Inspector面板下看到如下界面。


【风宇冲】Unity3D教程宝典之 <wbr>AnimationCurve


双击上图红色区域即进入曲线编辑界面(下图)。

【风宇冲】Unity3D教程宝典之 <wbr>AnimationCurve



双击任意区域内地方,创建关键点。对关键点点鼠标邮件,则出如下界面.

【风宇冲】Unity3D教程宝典之 <wbr>AnimationCurve



基本操作:


创建关键点:左键双击


删除关键点:


(1)鼠标移动至关键点上,右键->Delete Key。


(2)左键单击关键点,然后按键盘上的delete



设置曲线类型:鼠标移动至关键点上,右键->


Auto:根据关键点自动设置曲线。


Free Smooth:统一设置入切线和出切线


Flat:入切线和出切线为水平


Broken:分别设置入切线和出切线



也可以选Left Tangent(入切线)或者Right Tangent(出切线)或者Both Tangents(两切线)。


Free:自由曲线,与Broken效果基本一样。


Linear:线性曲线


Constant:之前一直是上个点的值,然后瞬间变为这个点的值。



其中Auto最简单,Broken调整空间最大。曲线效果以绿线为准。



编辑好一条曲线后,在曲线的左右两端会有一个下拉菜单,点击设置两端各自重复的方式。


Loop:曲线循环


【风宇冲】Unity3D教程宝典之 <wbr>AnimationCurve


Pingpong: 曲线和该曲线上下翻转后的曲线循环


【风宇冲】Unity3D教程宝典之 <wbr>AnimationCurve


Clamp:一直为端点的值。


【风宇冲】Unity3D教程宝典之 <wbr>AnimationCurve




第四步:使用曲线


在上面的脚本里,再添加几行代码,如下

1. using UnityEngine; 
2. using System.Collections; 
3. 
4. public class AnimationCurveTutor : MonoBehaviour { 
5. public AnimationCurve anim; 
6. public void Update() 
7. { 
8. transform.position = new Vector3(Time.time, anim.Evaluate(Time.time), 0); 
9. } 
10. }

运行后,物体会按曲线轨迹向右移动。

第三部分:脚本创建AnimationCurve


AnimationCurve可以理解为2部分。(1)键序列(2)左右循环模式(又作左右包裹模式)


一:键序列

创建键序列:Keyframe[] ks = newKeyframe[3];

曲线中加入键序列:AnimationCurve curve= newAnimationCurve(ks);

获取曲线中的键序列:curve[index]  

添加单键:curve.Addkey(time,value)


删除单键:curve.RemoveKey(index)


二:左右循环

anim.preWrapMode = 
 WrapMode.Loop; 

 
anim.postWrapMode = WrapMode.Once;

三:键

Keyframe kf = new Keyframe(time,value);
kf.inTangent = 45;
kf.outTangent = 45;



用脚本动态实时创建AnimationCurve。创建如下脚本,拖到任意物体运行即可。

1. using UnityEngine; 
2. using System.Collections; 
3. 
4. public class CreateRuntime : MonoBehaviour { 
5.    public AnimationCurve anim = new AnimationCurve(); 
6.    void Start() { 
7.        Keyframe[] ks = new Keyframe[3]; 
8.        ks[0] = new  Keyframe(0, 0); 
9.        ks[0].inTangent = 0; 
10.        ks[1] = new  Keyframe(4, 0); 
11.        ks[1].inTangent = 45; 
12.        ks[2] = new  Keyframe(8, 0); 
13.        ks[2].inTangent = 90; 
14.        anim = new AnimationCurve(ks); 
15.    } 
16.    void Update() { 
17.        transform.position = new  Vector3(Time.time, anim.Evaluate(Time.time),  0); 
18.    } 
19. }


第四部分:编辑器的AnimationCurve


.cs脚本如下。


使用时,先选中物体,再点击Unity菜单栏Examples->Mine,编辑好曲线后点击Generate Curve,之后运行即可。


【风宇冲】Unity3D教程宝典之 <wbr>AnimationCurve






1. using UnityEngine; 
2. using System.Collections; 
3. using UnityEditor; 
4. 
5. public class EditorCurves :EditorWindow {
6. AnimationCurve  curveX = AnimationCurve.Linear(0,0,10,10);
7. [MenuItem("Examples/Mine")]
8. static void Init()
9. {
10. EditorWindow  window = GetWindow(typeof(EditorCurves));
11. window.position =  new Rect(0,300,200,100);
12.        window.Show();
13. }
14. void OnGUI()
15. {
16.  curveX = EditorGUI.CurveField(new Rect(3,3,position.width-6,15), "Animation on X", curveX);
17. if(GUI.Button(new Rect(3,60,position.width-6,30),"Generate Curve"))
18.            AddCurveToSelectedGameObject();
19. }
20. void AddCurveToSelectedGameObject()
21. {
22. if(Selection.activeGameObject) {
23.            FollowAnimationCurveMine = Selection.activeGameObject.AddComponent<FollowAnimationCurveMine>();
24.            comp.SetCurves(curveX);
25.        } else {
26.            Debug.LogError("No Game Object selected for adding an animation curve");
27.        }
28. }
29. }

 


1. using  UnityEngine;
2. using  System.Collections;
3. 
4. public class FollowAnimationCurveMine  MonoBehaviour {
5. public AnimationCurve curveX;
6. public void SetCurves(AnimationCurve tmpCurve)
7. {
8. curveX = tmpCurve;
9. }
10. void Update () {
11. if(curveX != null)
12.    transform.position = new Vector3(1f*Time.time, curveX.Evaluate(Time.time) * 0.3f,0);
13. }
14. }