Unity动画曲线AnimationCurve的学习
在开发游戏的过程中,unity中的粒子系统,文字,UI界面的显示功能及一些其他的动态效果都可以使用AnimationCurve做一些自定义的曲线实现一些想要的效果。
1、AnimationCurve的创建
先创建脚本,public一个AnimationCurve对象如下图:
就会在Unity的Inspector面板上显示动画曲线自定义面板,如下图:
点击进去会发现一些自带的曲线函数,可以根据需求直接拿来用。也会发现上面的曲线所在的坐标系,就像我们数学学习的坐标系一样,每一个横坐标的值都会对应一个纵坐标的值(就像Dictionary的键值对),这里我们就能自己定义横坐标与纵坐标的含义来做一个动画。(例如横坐标当做时间,纵坐标当做轴值,当动画运行时这个轴值就会随着时间而增大,根据上图就是一个曲线增长,到达1秒时轴值也对应增长到1)
官方的AnimationCurve的API如下图
2、脚本中创建曲线
a)创建帧序列
Keyframe[] ks = new Keyframe[2];
b)曲线中加入帧序列
AnimationCurve Curve= new AnimationCurve(ks);
帧序列的相关设置
WrapMode.Loop是指整个循环左右循环。
WrapMode.Clamp指除了你设置的以外别的位置为直线。
WrapMode.PingPong指对称循环。
ks[index].inTangent是设置指入的切线的斜率,而ks[index].outTangent是设置出的切线斜率。
下面举一个别人写类似掉血飘字的实例
using UnityEngine;
using System.Collections;
public class BloodAnimation : MonoBehaviour {
private RectTransform rectTransform;
[SerializeField]
public AnimationCurve animationCurve; // 动画曲线
private int length; // 动画曲线关键帧个数
private Keyframe[] keyframs; // 动画曲线关键帧
// 文字初始坐标
private Vector3 bloodTextPos = Vector3.zero;
// Use this for initialization
void Start()
{
rectTransform = GetComponent<RectTransform>();
bloodTextPos = rectTransform.localPosition;
keyframs = animationCurve.keys; // 获取动画曲线关键帧
length = animationCurve.length; // 获取动画曲线关键帧个数
Debug.Log(length + " " + keyframs.Length);
// 遍历关键帧数组,打印每个关键帧的 time 和 value
for (int i = 0; i < keyframs.Length; i++)
{
Debug.Log(keyframs[i].time + " " + keyframs[i].value);
}
}
private float time = 0;
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.A))
{
animationCurve = CreateAnimationCurve();
}
GetAnimationCurveValue();
}
private void GetAnimationCurveValue()
{
if (keyframs.Length <= 0)
{
Debug.LogWarning("Keyframs Length is 0");
return;
}
if (time < keyframs[length - 1].time)
{
time += Time.deltaTime;
// 根据时间获取动画曲线相应点的 value
float value = animationCurve.Evaluate(time);
Debug.Log("time : " + time + " value : " + value);
Vector3 pos = rectTransform.localPosition;
pos.y = bloodTextPos.y + value;
// 设置文字坐标的 Y 值
rectTransform.localPosition = pos;
}
else
{
time = 0;
}
}
// 代码创建动画曲线
private AnimationCurve CreateAnimationCurve()
{
// 定义关键帧数组
Keyframe[] ks = new Keyframe[30];
int i = 0;
while (i < ks.Length)
{
// 给每个关键帧赋值 time, value
ks[i] = new Keyframe(i, Mathf.Sin(i));
i++;
}
// 设置前一个点进入该关键帧的切线(也就是设置斜率)
ks[1].inTangent = 45;
// 设置从 10 关键帧出去时的切线 (也是设置斜率)
ks[10].outTangent = 90;
// 通过关键帧数组实例化动画曲线
AnimationCurve animaCur = new AnimationCurve(ks);
//设置动画曲线最后一帧的 循环类型
animaCur.postWrapMode = WrapMode.Loop;
//设置动画曲线第一帧的 循环类型
animaCur.preWrapMode = WrapMode.Once;
Keyframe k = new Keyframe(31, 2);
// 添加一个动画帧
animaCur.AddKey(k);
// 移除第 10 个关键帧
animaCur.RemoveKey(10);
// 设置第 20 个关键帧 的平滑度
animaCur.SmoothTangents(20, 3);
// 根据时间获取动画曲线 time 时间点的 value
float time = 15.5f;
animaCur.Evaluate(time);
return animaCur;
}
}
在Unity场景中添加Canvas并创建一个文本框Text,并把上面脚本添加到该文本对象上,并选择或者创建一个曲线,如下:
然后点击运行,你会发现文本对象会按照曲线坐标发生循环移动。当你按下A键时,会调用脚本中的CreateAnimationCurve()函数赋给现在曲线对象,你会发现文本运动发生改变,曲线也会变成脚本中自定义的曲线,如下图:
AnimationCurve在游戏开发中应用很广,在做一些动态效果时也非常方便,上面只是一些基础案例,大家可以了解一下计算机图形学中的一些经典曲线,通过AnimationCurve创建出来应用在自己的案例里来做一些特殊的动态效果,或者增加更好的用户体验。