unity3d 动画曲线

2016-08-12 23:47:03 wkhabc 阅读数 6048
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

        通过动画事件,我们可以在动画过程中调用某个函数实现某种特定功能,如果我们需要在动画过程中调用多个函数,则需要在动画过程多个时间点插入动画事件。如果我们需要在动画中一个连续时间段中调用一个函数,则动画事件无法实现。可以说动画事件是在动画事件线进行离散式的事件调用。如果需要进行连续式的函数调用,则需要借助动画曲线,比如需要一段动画时间播放一段声音。
        动画曲线是动画剪辑(Animation Clip)的一个属性,这个属性由动画片段 (Animation Clip) 控制。带动画曲线 (Animation Curve) 的动画视图 (Animation View) 性的属性列表中有彩色曲线标记。
        假如,需要在如下Run动画剪辑的中间某段中播放一个声音,则可以将这一段的曲线区别于其他时间段,比如这一段的曲线值均大于0,其他时间段均小于0.
这里写图片描述
然后我们通过Animator Controller中设定参数,将参数名设定与Animation Curve一个名字,则将Animation Curve传递给Animator Controller中的参数。注意为让Animator Controller中的参数获取Animation Curve中的值,需要将Run的Animation中的Loop Pose取消。
这里写图片描述

然后我们可以通过如下代码获取到Animator Controller参数值,通过对这个值进行处理即可调用相关函数。

Float f=_animator.GetFloat("Test");
if(f>0){
//当参数值大于0,如何处理。
}else{
//当参数值小于0,如何处理。
}

此外,我们还可通过代码来控制Curves生成与编辑,以下转自转载自风宇冲Unity3D教程学院
第一部分:基本使用
第一步:创建物体
第二步:创建脚本
创建AnimationCurveTutor.cs的脚本并添加到物体上。代码如下。

using UnityEngine;
using System.Collections;
public class AnimationCurveTutor : MonoBehaviour {
public AnimationCurve anim;
}

第三步:绘制曲线
基本操作:
创建关键点:左键双击
删除关键点:
(1)鼠标移动至关键点上,右键->Delete Key。
(2)左键单击关键点,然后按键盘上的delete
设置曲线类型:鼠标移动至关键点上,右键->
Auto:根据关键点自动设置曲线。
Free Smooth:统一设置入切线和出切线
Flat:入切线和出切线为水平
Broken:分别设置入切线和出切线

也可以选Left Tangent(入切线)或者Right Tangent(出切线)或者Both Tangents(两切线)。
Free:自由曲线,与Broken效果基本一样。
Linear:线性曲线
Constant:之前一直是上个点的值,然后瞬间变为这个点的值。

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

编辑好一条曲线后,在曲线的左右两端会有一个下拉菜单,点击设置两端各自重复的方式。
第四步:使用曲线
在上面的脚本里,再添加几行代码,如下


using UnityEngine;
using System.Collections;

public class AnimationCurveTutor : MonoBehaviour {
public AnimationCurve anim;
public void Update()
{
transform.position = new Vector3(Time.time, anim.Evaluate(Time.time), 0);
}
}

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

第二部分:脚本创建Animation Curve
Animation Curve可以理解为2部分。(1)键序列(2)左右循环模式(又作左右包裹模式)
一:键序列
创建键序列:Keyframe[] ks = new Keyframe[3];
曲线中加入键序列:AnimationCurve curve = new AnimationCurve(ks);
获取曲线中的键序列:curve[index] 或者 curve.keys[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。创建如下脚本,拖到任意物体运行即可。

using UnityEngine;
using System.Collections;

public class CreateRuntime : MonoBehaviour {
    public AnimationCurve anim = new AnimationCurve();
    void Start() {
        Keyframe[] ks = new Keyframe[3];
        ks[0] = new Keyframe(0, 0);
        ks[0].inTangent = 0;
        ks[1] = new Keyframe(4, 0);
        ks[1].inTangent = 45;
        ks[2] = new Keyframe(8, 0);
        ks[2].inTangent = 90;
        anim = new AnimationCurve(ks);
    }
    void Update() {
        transform.position = new Vector3(Time.time, anim.Evaluate(Time.time), 0);
    }
}

2019-06-04 20:33:25 weixin_44370124 阅读数 1661
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

Unity中的动画曲线

Animation Curves on Imported Clips

动画曲线可以附加到动画导入设置的动画选项卡中的导入动画片段。

这些曲线允许您将额外的动画数据添加到导入的剪辑,这可以让您根据动画制作者的状态来动画其他项目的时间。例如,在冰冷条件下的游戏中,可以使用额外的动画曲线来控制粒子系统的发射速率,以显示玩家在冷空气中的冷凝呼吸。

要为导入的动画添加曲线,首先在项目视图中选择导入的动画文件,然后在检查器的导入设置中选择动画按钮。

展开curves标题,然后单击加号图标将新曲线添加到当前动画片段。如果导入的动画文件分割为多个动画片段,则每个片段都可以有自己的自定义曲线。

展开曲线标题,然后单击加号图标将新曲线添加到当前动画片段。如果导入的动画文件分割为多个动画片段,则每个片段都可以有自己的自定义曲线。
曲线的X轴表示标准化时间,并且始终在0.0和1.0之间(分别对应于动画片段的开始和结束,而不管其持续时间)。
在这里插入图片描述
在这里插入图片描述
动画曲线导入

创建关键点:左键双击

删除关键点:

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

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

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

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

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

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

**Broken:**分别设置入切线和出切线
也可以选Left Tangent(入切线)或者Right Tangent(出切线)或者Both Tangents(两切线)。

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

**Linear:**线性曲线

**Constant:**之前一直是上个点的值,然后瞬间变为这个点的值。
其中Auto最简单,Broken调整空间最大。曲线效果以绿线为准。

**Loop:**曲线循环

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

**Clamp:**一直为端点的值。
代码如下


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Curve : MonoBehaviour
{
    public AnimationCurve animationCurve;
    public Vector3 v3;
    // Start is called before the first frame update
    void Start()
    {
        v3 = transform.position;
    }

    // Update is called once per frame
    void Update()
    {
        transform.position = new Vector3(Time.time+v3.x, animationCurve.Evaluate(Time.time)+v3.y, v3.z);
    }
}


在这里插入图片描述把脚本挂载你想要的物体上就会按照你设置的这个曲线进行运动。

2017-02-28 18:33:21 LXL_815520 阅读数 3756
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

第一部分:介绍

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

第二部分:基本使用

第一步:创建物体
第二步:创建脚本
创建AnimationCurveTutor.cs的脚本并添加到物体上。代码如下。
  1. using UnityEngine;
  2. using System.Collections;
  3. public class AnimationCurveTutor : MonoBehaviour{
  4. public AnimationCurve anim;
  5. }
第三步:绘制曲线
把脚本添加到物体上后,物体的Inspector面板下看到如下界面。

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

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

基本操作:
创建关键点:左键双击
删除关键点:
(1)鼠标移动至关键点上,右键->Delete Key。
(2)左键单击关键点,然后按键盘上的delete

设置曲线类型:鼠标移动至关键点上,右键->
Auto:根据关键点自动设置曲线。
Free Smooth:统一设置入切线和出切线
Flat:入切线和出切线为水平
Broken:分别设置入切线和出切线

也可以选Left Tangent(入切线)或者Right Tangent(出切线)或者Both Tangents(两切线)。
Free:自由曲线,与Broken效果基本一样。
Linear:线性曲线
Constant:之前一直是上个点的值,然后瞬间变为这个点的值。

其中Auto最简单,Broken调整空间最大。曲线效果以绿线为准。
编辑好一条曲线后,在曲线的左右两端会有一个下拉菜单,点击设置两端各自重复的方式。
Loop:曲线循环

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

Clamp:一直为端点的值。

第四步:使用曲线
在上面的脚本里,再添加几行代码,如下
  1. using UnityEngine;
  2. using System.Collections;
  3. public class AnimationCurveTutor : MonoBehaviour {
  4. public AnimationCurve anim;
  5. public void Update()
  6. {
  7. transform.position = new Vector3(Time.time, anim.Evaluate(Time.time), 0);
  8. }
  9. }
运行后,物体会按曲线轨迹向右移动。

第三部分:脚本创建AnimationCurve

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

一:键序列

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

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

获取曲线中的键序列:curve[index]  或者 curve.keys[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. public class CreateRuntime : MonoBehaviour {
  4.     public AnimationCurve anim = new AnimationCurve();
  5.     void Start() {
  6.         Keyframe[] ks = new Keyframe[3];
  7.         ks[0] = new Keyframe(00);
  8.         ks[0].inTangent = 0;
  9.         ks[1] = new Keyframe(40);
  10.         ks[1].inTangent = 45;
  11.         ks[2] = new Keyframe(80);
  12.         ks[2].inTangent = 90;
  13.         anim = new AnimationCurve(ks);
  14.     }
  15.     void Update() {
  16.         transform.position = new Vector3(Time.time, anim.Evaluate(Time.time), 0);
  17.     }
  18. }

第四部分:编辑器的AnimationCurve

创建EditorCurves.cs及FollowAnimationCurveMine.cs脚本如下。
使用时,先选中物体,再点击Unity菜单栏Examples->Mine,编辑好曲线后点击Generate Curve,之后运行即可。

 

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

  1. using UnityEngine;
  2. using System.Collections;

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

2017-09-05 16:54:52 m0_37250299 阅读数 2840
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

有时候在编辑Animation动画时会出现这样的问题,一个Key和下一个Key的状态是一模一样的,但是当运行动画的时候,在它们之间却产生了动画效果。

比如下图这个动画,Line:Scale在0:00和0:20时的状态都是(0,1,1)。




但是在它们之间Scale却产生了变化。




解决方法:点击Animation窗口下方的Curves,发现动画略有弯曲。右键0:20时的Key,将其设置为Flat就可以了。





2015-12-11 09:47:12 LIQIANGEASTSUN 阅读数 17544
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

Unity 动画曲线-AnimationCurve 实例

以Unity 自带的动画曲线实现一些简单的动画,如往复运动,曲线运动,不规则运动,掉血飘字等。

下面先上代码

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;
    }
}

使用如下:
一、如上定义了 [SerializeField]
public AnimationCurve animationCurve; // 动画曲线

看Inspector 面板显示如下

这里写图片描述

二、编辑曲线
点击曲线弹出窗口
这里写图片描述

新建曲线
这里写图片描述

设置曲线循环类型
这里写图片描述

设置关键帧 time、value, 两种选手动拖和设置
这里写图片描述

详细设置如下
这里写图片描述

选择 EditKey 如下
这里写图片描述

随意设置结果如下
这里写图片描述

然后运行项目,看 文字 运动变化
这里写图片描述

这里写图片描述

上面是手动设置曲线,上面代码中已写了一个 代码设置曲线的例子,调用 CreateAnimationCurve() 方法即可