前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Unity基础(23)-动画系统

Unity基础(23)-动画系统

作者头像
孙寅
发布2020-06-02 11:52:43
1.9K0
发布2020-06-02 11:52:43
举报
文章被收录于专栏:宜达数字宜达数字

1.png

Unity3D动画系统

分为旧版动画系统和新版动画(Mecanim)系统即Animation 与 Animator

Mecanim概述:

Mecanim是Unity提供第一个丰富而复杂的动画系统,提供了: 针对人形角色的简易的工作流和动画创建能力 Retargeting(运动重定向)功能,即把动画从一个角色模型应用到另一个角色模型上的能力。 针对Animations Clips(动画片段)的简易工作流,针对动画片段及他们之间的过度和交互预览能力。 一个用于管理动画间复杂交互作用的可视化窗口。 通过不同逻辑来控制不同身体部位的运动能力。

Paste_Image.png

1、Animation动画状态机

Animation是U3D旧版的动画状态机,我们一般将模型中的动画放入其中,通过代码开执行动画。

代码语言:javascript
复制
// 拿到Animation组件
Animation Ani = GetComponent<Animation>();
// 执行已经放入其中的动画片段
Ani.CrossFade("Walk"); // 默认就是正播
Ani["Walk"].speed = 1f;

Ani["Walk"].speed = -1f; // 如果是-1 那就是倒着播放
Ani.CrossFade("Walk");
2、Animator动画状态机

Paste_Image.png

Paste_Image.png

其实到这里,我们应该想一个角色模型上面有什么?

2-1.U3D角色模型拥有什么属性?

Paste_Image.png

导入进Unity3D的模型属性:

Paste_Image.png

Paste_Image.png

2-2.将制作好的角色模型导入Unity3D中是什么样?

Paste_Image.png

2-3.新的Mecanim动画系统多了什么东西呢?

Paste_Image.png

我们可以看出多了一个普通,标准动画,和一套类人体骨骼动画。

2-4.二者之间有什么区别呢?

Generic: 这是为任何东西像是人,有动画的柱子,四足动物之类设计的。重定向在这里是不支持的,但是你仍然可以得到后文中描述的Mecanim的好处。 Humanoid: Mecanim对于类人角色有一个特别的工作流,使用扩展后的GUI和重定向。配置包含创建和设定一个Avatar并且调整肌肉定义。 类人体骨骼动画就是由Unity3D软件根据动画模型的骨骼系统创建一套自己的Avatar. 何一个拥有avatar的GameObject都将拥有一个Animator组件用来连接角色和他的行为。 Avatar: 是一个将一个角色的骨骼信息重定向到另一个角色上的接口。(下图展示就是一个Avatar) 我们一般查看内部的骨骼有没有错误,或者肌肉的伸展有没有问题.(如果在公司,那么有问题也轮到开发人员去调整,模型师会帮助你完成)

Paste_Image.png

视频教程: http://www.youku.com/playlist_show/id_29528034.html

3、Animator-事件系统
1-添加事件

Paste_Image.png

Paste_Image.png

2-我们添加脚本监听书写的事件方法

方法名字一定要与你请的事件名字一致

Paste_Image.png

Paste_Image.png

注意:在拥有动画状态机的那一级添加脚本才能实现,不然会报错(就是在角色身上添加脚本,实现事件才不会出错)

4、Animator-拆分动画

如果贵公司的UI很认真,那么你就省去大把时间来拆分动画了.如果没有,那么你就需要拆分动画了

Paste_Image.png

1-动画片段其他属性: Apply Root Motion

Paste_Image.png

Bake into Pose

Paste_Image.png

我们首先来看这个“Bake into Pose".在untiy中将动画中的变换分成两种,Body Transform和Root Transform,我们可以设置动画中的关于模型的一些变换(平移、旋转等)是属于Body Transform(pose)还是Root Transform(trajectory)的一部分。这里的Bake into Pose 也就是将变换设置为Body Transform(pose)的一部分。我们可以这样去理解,如果是设置成Body Transform(pose)的话,就相当这些变换是属于动画本身的一部分,也就是说,不管设不设置Apply Root Motion,在场景中,我们都会看到模型位置或角度的变化。(因为Body Transform不影响模型实际的位置和角度,所以这里只是纯粹的动画效果,模型的位置和角度参数值不变),如果设置成Root Transform,Root Transform将影响模型的实际位置和角度(前提是要设置“Apply Root Motion”,如果不设置Apply Root Motion的话,也就是说变换将不应用,场景中的模型位置或角度是不会有变化的(参数值自然也不变),就像一个行走动画,可能一直在原地行走)。 然后我们来重点再看看这里的”Apply Root Motion".这里他会起到两个作用,首先最重要的是,决定是否应用Root Transform,如果应用的话,那么在动画的同时,模型的位置和角度会同时跟着变化。如果这里不勾选的话,那么就是说不应用Root Transform,这样我们所有的Root Transform都将不起任何作用。(也就相当于于所有没有Bake into Pose 的变换都没有用了)。 Apply Root Motion的第二个作用是在动画结束后,将Body Transform中的变化应用到模型(注意,这里是结束的时候才应用,也就是说动画的时候,模型的position、rorate等参数是不变的,当动画结束之后,开始新的动画之前才会改变,注意这里跟前面提到的Root Transform的区别)

1、勾选”Bake into Pose",不勾选“Apply Root Motion",勾选”Bake into Pose"后,变换属于Body Transform,所以即使这里未勾选”Apply Root Motion“,但是动画依然会在场景中体现,人物会按照动画的路径行走(但是如果我们观察Inspector中模型的position参数,值一直不变)。但是因为没有勾选Apply Root Motion,所以动画结束后,变换不会应用到模型,所以如果这时候,如果开始一个新的动画的话,模型会瞬间回到起始位置(新的动画开始时候,模型处于行走动画开始时的位置)。

2、勾选”Bake into Pose",并勾选“Apply Root Motion",这里跟上面的情况唯一不同的就是,动画结束后,开始新的动画之前,变换会应用到模型。(模型的position在新的动画开始之前会发生变化,新的动画开始时候,模型处于动画结束时的位置)

3、不勾选”Bake into Pose",勾选“Apply Root Motion",这时候,变换是作为Root Transform,所以因为这里勾选了Apply Root Motion,变换会应用到模型(模型的position跟着动画不停的变化),自然,新的动画开始时候,模型处于动画结束时的位置。

4、不勾选”Bake into Pose",并且不勾选“Apply Root Motion",这里变化还是作为Root Transform,但是因为没有勾选Apply Root Motion,所以变换将不被应用,所以模型将一直在本地不动,自然,新的动画开始时候,模型处于行走动画开始时的位置

视频教程: http://www.youku.com/playlist_show/id_29528034.html 详细介绍,参考:http://blog.csdn.net/cubesky/article/details/39478207

5、Animator-动画状态机,动画控制器
1、手动创建(动画控制器)AnimatorController:

Paste_Image.png

Paste_Image.png

还可以这样打开:

Paste_Image.png

2、代码创建(动画控制器)AnimatorController:
代码语言:javascript
复制
using System.Collections;
using UnityEditor;
using UnityEditor.Animations;//5.0改变 UnityEditorInternal;并不能用了。
 
public class CreateAnimatorController : Editor 
{
    [MenuItem("ModelConfig/创建Controller")]
    static void DoCreateAnimationAssets()
    {
        //创建Controller
        AnimatorController animatorController = AnimatorController.CreateAnimatorControllerAtPath("Assets/animation.controller");
        //得到它的Layer
        AnimatorControllerLayer layer = animatorController.layers[0];
        //将动画保存到 AnimatorController中
        AddStateTransition("Assets/Art Resources/Character/moster-002/basic/moster-002@run.FBX", layer);
        AddStateTransition("Assets/Art Resources/Character/moster-002/basic/moster-002@stand.FBX", layer);
        AddStateTransition("Assets/Art Resources/Character/moster-002/basic/moster-002@born.FBX", layer);
    }
 
    private static void AddStateTransition(string path, AnimatorControllerLayer layer)
    {
        AnimatorStateMachine sm = layer.stateMachine;
        //根据动画文件读取它的AnimationClip对象
        AnimationClip newClip = AssetDatabase.LoadAssetAtPath(path, typeof(AnimationClip)) as AnimationClip;
        
        ////取出动画名子 添加到state里面
        AnimatorState state = sm.AddState(newClip.name);
        //5.0改变
        state.motion = newClip;
        Debug.Log(state.motion);
        //把state添加在layer里面
        AnimatorStateTransition trans = sm.AddAnyStateTransition(state);
    }
}

补充: inspector有一个debug模式,你在debug模式下修改一下Animation Type为0 就可以了 Unity有两套Animation系统,一套是legacy,一套是Mecanim。 Debug模式下的Animation Type 0表示Mecanim,可以用于animator;1表示Legacy,用于animation组件。

之前已经写过两套的动画系统,今天主要分享关于动画层的使用及注意事项

这个就是层的概念

6、为什么动画中会有层的概念

其实在新版的动画状态机中,大量的技巧已经让一般的小白晕头转向了。而且就目前来说:使用状态机的单一层动画就已经可以满足日常开发需要。那么为什么出现层的概念呢? 先来几张图,对比一下,你就会发现哪里好

其实我们已经可以发现这种好处了,类似项目管理

第一:分离动画组 第二:规范动画制作 第三:提供更丰富的动画制作 Ps:其实跟我们的动画融合树差不多。。。

2.如何使用层动画?

01-添加动画层

添加层

注意:同一时刻我们只能执行一个层的动画片段。 02-添加参数

Paste_Image.png

注意:参数是执行动画的触发条件

03-给第二层的触发线绑定参数

Paste_Image.png

绑定的过程中,其实我们会发现New State就代指第一层动画组,而参数帮助我们过渡了层。当然动画是显示不出来的,但是动画片段确实执行了。

3.注意点?

在动画层之间切换的过程中,其实主要是通过参数的满足与否来进行层动画执行操作,但是有一个前提就是层的权重 如下图:

权重问题决定动画能不能显示出来

如果不设置权重,你会发现即便分好层,而且在状态机中发现动画执行了,但是界面的角色并没有显示出来。

前面的分享已经提到过使用代码控制动画的参数,这里如何通过代码设置权重呢?

代码语言:javascript
复制
    [SerializeField]
    private Animator ani;
    void Start () {
        // 表示设置动画第二层的权重为1
        ani.SetLayerWeight(1, 1);
    }

视频教程: http://www.youku.com/playlist_show/id_29528034.html

方反向运动学

7、反向动力学:IK
1:什么是反向动力学?

一般我们都是通过父节点来调动子节点运动,而在实际开发过程中,有时候我们需要子节点带动父节点进行相应的动作。这种情况就是反向动力学。其实在国内的游戏中很少看见IK动画,一般而言国外的游戏较多。例如刺客信条,手部带动身体的爬行。 通俗讲:使用场景中的各种物体来控制和影响角色身体部位的运动

2:IK能做什么?

一般来说,我们在特定的场景下,需要我们的游戏对象一起看向某一个游戏环境或者游戏其他对象。而这个时候,反向运动学就可以让我们很好的做到这种效果。

3:案例介绍

上图的案例就是游戏人物盯着某个游戏对象看,来达到时刻注视的效果。 首先打开IK开关

打开开关会显示IK字样

代码语言:javascript
复制
    [SerializeField]
    private Animator ani;
    public GameObject target;
    void Start() {
        // 表示设置动画第二层的权重为1
        ani.SetLayerWeight(1, 1);
    }
    // 特定方法
    void OnAnimatorIK(int layerIndex)
    {
        ani.SetLookAtWeight(1);
        //身体的IK就是+参数
       // ani.SetLookAtWeight(1,1,1,1);
        if (target.transform != null)
        {
            ani.SetLookAtPosition(target.transform.position);
        }

更复杂一点,就是让身体也跟着注释的对象移动或摆动

代码语言:javascript
复制
    [SerializeField]
    private Animator ani;
    public GameObject target;
    public Transform leftVec;
    public Quaternion qua;
    void Start() {
        // 表示设置动画第二层的权重为1
        ani.SetLayerWeight(1, 1);
        //mask.positionXYZWeight = new Vector3(0,1,1);
        //mask.rotationWeight = 1;                    
       }


    void Update() {
        qua = Quaternion.Euler(target.position);
    }
    void OnAnimatorIK(int layerIndex)
    {
        ani.SetLookAtWeight(1);
        if (target.transform != null)
        {
            ani.SetLookAtPosition(target.transform.position);
        }
        // 设置左手的IK
        ani.SetIKPositionWeight(AvatarIKGoal.LeftHand, 1);
        ani.SetIKRotationWeight(AvatarIKGoal.LeftHand, 1);
        if(leftVec != null)
        {
            ani.SetIKPosition(AvatarIKGoal.LeftHand, target.transform.position);
            ani.SetIKRotation(AvatarIKGoal.LeftHand, qua);
        }
    }
}

投篮姿势

复杂一点,根据动画来约束游戏对象的身体某一部位到达指定位置

代码语言:javascript
复制
    public Animator ani;
    public Transform LeftHand;
    bool hasJump = false;
    void Start () {
        ani = GetComponent<Animator>();
    }
    
    
    void Update () {
        if (ani)
        {
            AnimatorStateInfo info = ani.GetCurrentAnimatorStateInfo(0);
            
            if (Input.GetKeyDown(KeyCode.Space))
            {
                ani.SetBool("Jump", true);
              
            }
            if (info.IsName("Base Layer.Vault"))
            {
                ani.SetBool("Jump", false);
                // 第一个参数动作位置,第二个参数角色旋转,第三个是做动作的某个身体部位,第四个是权重信息,第五六参数是获取动画曲线
                ani.MatchTarget(LeftHand.position, LeftHand.rotation, AvatarTarget.LeftFoot, new MatchTargetWeightMask(new Vector3(1, 1, 1), 0), ani.GetFloat("StartA"), ani.GetFloat("EndA"));
                hasJump = true;
            }
        }
    }
}
4:IK相关的插件

Paste_Image.png

FinalIK,这个我没有研究过,但听说效果不错。可以去看看,官方商店是有的,有机会研究吧。。。

视频教程: http://www.youku.com/playlist_show/id_29528034.html

8、TimeLine使用
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Unity3D动画系统
    • Mecanim概述:
      • 1、Animation动画状态机
        • 2、Animator动画状态机
          • 2-1.U3D角色模型拥有什么属性?
          • 2-2.将制作好的角色模型导入Unity3D中是什么样?
          • 2-3.新的Mecanim动画系统多了什么东西呢?
        • 2-4.二者之间有什么区别呢?
          • 3、Animator-事件系统
            • 1-添加事件
            • 2-我们添加脚本监听书写的事件方法
          • 4、Animator-拆分动画
            • 5、Animator-动画状态机,动画控制器
              • 1、手动创建(动画控制器)AnimatorController:
              • 2、代码创建(动画控制器)AnimatorController:
            • 6、为什么动画中会有层的概念
              • 2.如何使用层动画?
              • 3.注意点?
            • 7、反向动力学:IK
              • 1:什么是反向动力学?
              • 2:IK能做什么?
              • 3:案例介绍
              • 4:IK相关的插件
            • 8、TimeLine使用
            相关产品与服务
            图像处理
            图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档