33.老Animation动画系统

  1. 33.动画基础-Animation动画窗口-代码控制老动画系统
    1. 33.1 知识点
      1. 什么是老动画系统
      2. 老动画系统控制动画播放
        1. 注意
        2. 老动画系统创建Animation前要给生成动画的对象添加Animation脚本,挂载过后Unity就会认为这个对象要使用老动画系统。
        3. 挂载过会按老套路在Animation窗口新建Animation动画,选择文件夹存储。
        4. 因为对象添加了Animation组件,创建后Unity不会自动创建Animator文件并且给对象添加Animator组件。只会把新创建的Animation文件和Animation组件关联。Animation窗口上的操作和之前一模一样。
        5. 要注意老版本创建出来的Animation文件上的参数和新版本是不同的。
      3. 老Animation参数
        1. 老Animation组件参数
        2. 老Animation文件参数
      4. 老Animation动画系统代码控制
        1. 要把脚本挂载到对象上,用脚本得到Animation组件
        2. Update内
          1. Animation.Play方法 播放动画
          2. Animation.CrossFade方法 淡入播放,自动产生过渡效果
          3. Animation.PlayQueued方法 前一个播完直接再播放下一个
          4. Animation.CrossFadeQueued方法 前一个播完淡入播放下一个
          5. Animation.Stop方法 停止播放所有动画
          6. Animation.IsPlaying方法 是否在播放某个动画
          7. Animation.wrapMode变量 播放模式设置
          8. 其它(了解即可,新动画系统中会详细讲解)
      5. 老动画系统动画事件
        1. 在Animation窗口选择某一动画的某一帧下,点击添加动画事件的按钮添加动画事件。
        2. 添加后可以在时间轴看到一个蓝色的条。蓝色的条可以在时间轴任意拖动。点击可以在右侧Inspector窗口看见动画事件相关参数,现在还没有绑定任何事件。
        3. 在挂载到执行动画对象上的代码上添加用于动画事件关联的函数。函数可以有参数,可以是int,float,GameObject类型。
        4. 在动画事件绑定函数。注意当动画执行到动画事件的那一帧时会执行绑定的函数。
      6. 总结
    2. 33.2 知识点代码
    3. 33.3 练习题
      1. 使用Animation相关知识,请自己用Unity自带几何体拼凑一个机器人,有手有脚,为它制作两个动作,一个待机动作(站立不动),一个走路动作,我们可以通过键盘控制它移动切换动作
        1. 在场景中通过创建球体,立方体,胶囊体拼成一个机器人。注意有些不为要添加关节空物体用于管理机器人的部位。
        2. 给机器人根对象添加Animation组件
        3. 创建Idle和Move两个动画Animation文件,修改动画在关键帧的旋转的角度。实现待机的时候轻微摆手,跑步的时候摆臂两个动画。两个动画都设置成循环播放。而且要注意的是要在第一帧设置各个关节的旋转为0。不然的话Move动画切换成Idle动画的时候会有问题。因为切换回来的时候没有重置关节位置的话关节会保持Move动画最后一帧的位置。注意录制的时候因为旋转位置默认是0,要先把旋转位置先设置成别的值再改回0才能添加关键帧。
        4. 给机器人根对象添加脚本。脚本中得到Animation组件,根据玩家输入进行切换动画并移动。
    4. 33.4 练习题代码

33.动画基础-Animation动画窗口-代码控制老动画系统


33.1 知识点

什么是老动画系统

Unity中有两套动画系统:

  • 新:Mecanim动画系统——主要用Animator组件控制动画。
  • 老:Animation动画系统——主要用Animation组件控制动画(Unity4之前的版本可能会用到)。

目前我们为对象在Animation窗口创建的动画都会被新动画系统支配。有特殊需求或者针对一些简易动画,才会使用老动画系统。

老动画系统控制动画播放

注意

在创建动画之前为对象添加Animation组件之后再制作动画。
这时制作出的动画和之前的动画格式是有区别的。

老动画系统创建Animation前要给生成动画的对象添加Animation脚本,挂载过后Unity就会认为这个对象要使用老动画系统。



挂载过会按老套路在Animation窗口新建Animation动画,选择文件夹存储。

因为对象添加了Animation组件,创建后Unity不会自动创建Animator文件并且给对象添加Animator组件。只会把新创建的Animation文件和Animation组件关联。Animation窗口上的操作和之前一模一样。

要注意老版本创建出来的Animation文件上的参数和新版本是不同的。

老Animation参数

老Animation组件参数


  • Animation:默认播放的动画。
  • Animations:该动画组件可以控制的所有动画,对对象新创建老版本的Animation后会自动添加关联到这里。
  • Play AutoMatically:是否一开始就自动播放默认动画。
  • Animate Physics:动画是否与物理交互。
  • Culling Type:决定什么时候不播放动画。
    • Always Animate:始终播放。
    • Based On Renderers:基于默认动画姿势剔除,比如动画在屏幕外可能就不播了。

老Animation文件参数


  • Default:读取设置得更高的默认重复模式。
  • Once:播放一次就停止。
  • Loop:从头到尾不停循环播放。
  • ClampForever:播放结束会停在最后一帧,并且会一直播放最后一帧(相当于状态不停止),表现效果和Once一样,但是逻辑处理上不同。
  • PingPong:从头到尾从尾到头不停播放。

老Animation动画系统代码控制

要把脚本挂载到对象上,用脚本得到Animation组件

private Animation animation;

void Start()
{
    animation = this.GetComponent<Animation>();
}

Update内

Animation.Play方法 播放动画
//Animation的Play方法 播放动画
//播放没有混合的动画。
//会直接生硬的切换动画 假如播放到一半切换动画 回强行停止第一个播放的动画 切换到第二个播放动画的初始状态 进行播放
if (Input.GetKeyDown(KeyCode.Alpha1))
{
    animation.Play("1");
}
if (Input.GetKeyDown(KeyCode.Alpha2))
{
    animation.Play("2");
}
Animation.CrossFade方法 淡入播放,自动产生过渡效果
//Animation的CrossFade方法 淡入播放,自动产生过渡效果
//在后续 time 秒的时间段内,使名称为 animation 的动画淡入,使其他动画淡出。
//会先淡出把状态慢慢变成要播放的动画的初始在状态,再播动画
if (Input.GetKeyDown(KeyCode.Alpha3))
{
    //当你要播放的动画的开始状态 和当前的状态 不一样时 
    //就会产生过渡效果
    animation.CrossFade("3");
    //animation.Play("3");
}
Animation.PlayQueued方法 前一个播完直接再播放下一个
//Animation的PlayQueued方法 前一个播完直接再播放下一个
//在先前的动画播放完毕后再播放动画。
//可以理解为把动画加到队列中 等上一个动画播放完再播 会生硬的切换初始状态
if (Input.GetKeyDown(KeyCode.Alpha4))
{
    animation.PlayQueued("2");
}
Animation.CrossFadeQueued方法 前一个播完淡入播放下一个
//Animation的CrossFadeQueued方法 前一个播完淡入播放下一个
//使动画在上一个动画播放完成后交叉淡入淡出。
//可以理解为把动画加到队列中 等上一个动画播放完再播 会先淡出把状态慢慢变成要播放的动画的初始在状态,再播动画
if ( Input.GetKeyDown(KeyCode.Alpha5) )
{
    animation.CrossFadeQueued("2");
}
Animation.Stop方法 停止播放所有动画
//Animation的Stop方法 停止播放所有动画
//停止所有使用该动画启动的正在播放的动画。
//animation.Stop();
Animation.IsPlaying方法 是否在播放某个动画
//Animation的IsPlaying方法 是否在播放某个动画
//名称为 name 的动画是否正在播放?
if ( animation.IsPlaying("1") )
{

}
Animation.wrapMode变量 播放模式设置
//Animation的wrapMode变量 播放模式设置
//应如何处理超出此剪辑播放范围的时间?
//可以进去看枚举
//animation.wrapMode = WrapMode.Loop;//设置成循环播放
其它(了解即可,新动画系统中会详细讲解)
//其它(了解即可,新动画系统中会详细讲解)
//层级和权重以及混合(老动画系统需要通过代码来达到动画的遮罩、融合等效果)
//设置层级
//animation["1"].layer = 1;
//设置权重
//animation["1"].weight = 1;
//混合模式 叠加还是混合
//animation["1"].blendMode = AnimationBlendMode.Additive;
//设置混组相关骨骼信息
//animation[""].AddMixingTransform();

老动画系统动画事件

动画事件主要用于处理当动画播放到某一时刻想要触发某些逻辑,比如进行伤害检测、发射子弹、特效播放等等。

在Animation窗口选择某一动画的某一帧下,点击添加动画事件的按钮添加动画事件。

添加后可以在时间轴看到一个蓝色的条。蓝色的条可以在时间轴任意拖动。点击可以在右侧Inspector窗口看见动画事件相关参数,现在还没有绑定任何事件。

在挂载到执行动画对象上的代码上添加用于动画事件关联的函数。函数可以有参数,可以是int,float,GameObject类型。

public void AnimationEvent(GameObject go)
{
    print("动画事件触发");
}

在动画事件绑定函数。注意当动画执行到动画事件的那一帧时会执行绑定的函数。


总结

老动画系统主要用于处理老版本项目和简单的一些自制动画。

新项目都不建议大家使用了。

关键组件:Animation


33.2 知识点代码

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

public class Lesson33_动画基础_Animation动画窗口_代码控制动画 : MonoBehaviour
{
    private Animation animation;
    
    void Start()
    {
        #region 知识点一 什么是老动画系统
        //Unity中有两套动画系统
        //新:Mecanim动画系统——主要用Animator组件控制动画
        //老:Animation动画系统——主要用Animation组件控制动画(Unity4之前的版本可能会用到)

        //目前我们为对象在Animation窗口创建的动画都会被新动画系统支配
        //有特殊需求或者针对一些简易动画,才会使用老动画系统
        #endregion

        #region 知识点二 老动画系统控制动画播放
        //注意:
        //在创建动画之前为对象添加Animation组件之后再制作动画
        //这时制作出的动画和之前的动画格式是有区别的

        //Animation参数相关
        #endregion

        #region 知识点三 代码控制老动画系统播放

        //得到Animation组件
        animation = this.GetComponent<Animation>();
        //1.播放动画

        //2.淡入播放,自动产生过渡效果

        //3.前一个播完再播放下一个

        //4.停止播放所有动画

        //5.是否在播放某个动画

        //6.播放模式设置

        //7.其它(了解即可,新动画系统中会详细讲解)
        //层级和权重以及混合(老动画系统需要通过代码来达到动画的遮罩、融合等效果)
        //设置层级
        //设置权重
        //混合模式 叠加还是混合
        //设置混组相关骨骼信息
        #endregion

        #region 知识点四 老动画系统动画事件
        //动画事件主要用于处理 当动画播放到某一时刻想要触发某些逻辑
        //比如进行伤害检测、发射子弹、特效播放等等
        #endregion

        #region 总结
        //老动画系统主要用于处理老版本项目和简单的一些自制动画
        //新项目都不建议大家使用了

        //关键组件:Animation
        #endregion
    }


    #region 知识点四 动画事件
    public void AnimationEvent(GameObject go)
    {
        print("动画事件触发");
    }
    #endregion

    #region 知识点三 代码控制老版本动画播放
    
    void Update()
    {
        //Animation的Play方法 播放动画
        //播放没有混合的动画。
        //会直接生硬的切换动画 假如播放到一半切换动画 回强行停止第一个播放的动画 切换到第二个播放动画的初始状态 进行播放
        if (Input.GetKeyDown(KeyCode.Alpha1))
        {
            animation.Play("1");
        }
        if (Input.GetKeyDown(KeyCode.Alpha2))
        {
            animation.Play("2");
        }

        //Animation的CrossFade方法 淡入播放,自动产生过渡效果
        //在后续 time 秒的时间段内,使名称为 animation 的动画淡入,使其他动画淡出。
        //会先淡出把状态慢慢变成要播放的动画的初始在状态,再播动画
        if (Input.GetKeyDown(KeyCode.Alpha3))
        {
            //当你要播放的动画的开始状态 和当前的状态 不一样时 
            //就会产生过渡效果
            animation.CrossFade("3");
            //animation.Play("3");
        }


        //Animation的PlayQueued方法 前一个播完直接再播放下一个
        //在先前的动画播放完毕后再播放动画。
        //可以理解为把动画加到队列中 等上一个动画播放完再播 会生硬的切换初始状态
        if (Input.GetKeyDown(KeyCode.Alpha4))
        {
            animation.PlayQueued("2");
        }


        //Animation的CrossFadeQueued方法 前一个播完淡入播放下一个
        //使动画在上一个动画播放完成后交叉淡入淡出。
        //可以理解为把动画加到队列中 等上一个动画播放完再播 会先淡出把状态慢慢变成要播放的动画的初始在状态,再播动画
        if ( Input.GetKeyDown(KeyCode.Alpha5) )
        {
            animation.CrossFadeQueued("2");
        }

        //Animation的Stop方法 停止播放所有动画
        //停止所有使用该动画启动的正在播放的动画。
        //animation.Stop();

        //Animation的IsPlaying方法 是否在播放某个动画
        //名称为 name 的动画是否正在播放?
        if ( animation.IsPlaying("1") )
        {

        }

        //Animation的wrapMode变量 播放模式设置
        //应如何处理超出此剪辑播放范围的时间?
        //可以进去看枚举
        //animation.wrapMode = WrapMode.Loop;//设置成循环播放

        //其它(了解即可,新动画系统中会详细讲解)
        //层级和权重以及混合(老动画系统需要通过代码来达到动画的遮罩、融合等效果)
        //设置层级
        //animation["1"].layer = 1;
        //设置权重
        //animation["1"].weight = 1;
        //混合模式 叠加还是混合
        //animation["1"].blendMode = AnimationBlendMode.Additive;
        //设置混组相关骨骼信息
        //animation[""].AddMixingTransform();
    }

    #endregion
}

33.3 练习题

使用Animation相关知识,请自己用Unity自带几何体拼凑一个机器人,有手有脚,为它制作两个动作,一个待机动作(站立不动),一个走路动作,我们可以通过键盘控制它移动切换动作

在场景中通过创建球体,立方体,胶囊体拼成一个机器人。注意有些不为要添加关节空物体用于管理机器人的部位。

给机器人根对象添加Animation组件

创建Idle和Move两个动画Animation文件,修改动画在关键帧的旋转的角度。实现待机的时候轻微摆手,跑步的时候摆臂两个动画。两个动画都设置成循环播放。而且要注意的是要在第一帧设置各个关节的旋转为0。不然的话Move动画切换成Idle动画的时候会有问题。因为切换回来的时候没有重置关节位置的话关节会保持Move动画最后一帧的位置。注意录制的时候因为旋转位置默认是0,要先把旋转位置先设置成别的值再改回0才能添加关键帧。


给机器人根对象添加脚本。脚本中得到Animation组件,根据玩家输入进行切换动画并移动。

//定义私有变量animation,用于存储角色的Animation组件
private Animation animation;

//定义私有变量isMoving,用于记录角色是否处于移动状态
private bool isMoving;

//在脚本启动时调用,获取角色的Animation组件
void Start()
{
    animation = this.GetComponent<Animation>();
}

//每帧更新一次,根据玩家输入和角色状态更新角色的位置和动画状态
void Update()
{
    //当按下W键时,切换角色动画为Move,并将isMoving标记为true
    if (Input.GetKeyDown(KeyCode.W))
    {
        animation.CrossFade("Move");
        isMoving = true;
    }
    //当松开W键时,切换角色动画为Idle,并将isMoving标记为false
    else if (Input.GetKeyUp(KeyCode.W))
    {
        animation.CrossFade("Idle");
        isMoving = false;
    }

    //当角色处于移动状态时,让角色沿着前方方向持续移动
    if (isMoving)
        this.transform.Translate(Vector3.forward * 5 * Time.deltaTime);
}

33.4 练习题代码

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

public class Lesson33_练习题 : MonoBehaviour
{
    #region 练习题一
    //使用Animation相关知识
    //请自己用Unity自带几何体拼凑一个机器人,有手有脚
    //为它制作两个动作,一个待机动作(站立不动),一个走路动作
    //我们可以通过键盘控制它移动切换动作

    //定义私有变量animation,用于存储角色的Animation组件
    private Animation animation;

    //定义私有变量isMoving,用于记录角色是否处于移动状态
    private bool isMoving;

    //在脚本启动时调用,获取角色的Animation组件
    void Start()
    {
        animation = this.GetComponent<Animation>();
    }

    //每帧更新一次,根据玩家输入和角色状态更新角色的位置和动画状态
    void Update()
    {
        //当按下W键时,切换角色动画为Move,并将isMoving标记为true
        if (Input.GetKeyDown(KeyCode.W))
        {
            animation.CrossFade("Move");
            isMoving = true;
        }
        //当松开W键时,切换角色动画为Idle,并将isMoving标记为false
        else if (Input.GetKeyUp(KeyCode.W))
        {
            animation.CrossFade("Idle");
            isMoving = false;
        }

        //当角色处于移动状态时,让角色沿着前方方向持续移动
        if (isMoving)
            this.transform.Translate(Vector3.forward * 5 * Time.deltaTime);
    }


    #endregion
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏