unity的Mecanim动画系统

版权声明:未经本人同意不得转载 https://blog.csdn.net/jjjndk1314/article/details/84993357

Mecanim新特性

1.针对人形角色提供了一种特殊的工作流,包含Avatar的创建和对肌肉的调节。
2.动画重定向的能力,可以非常方便地把动画从一个角色模型应用到其他角色模型上。
3. 提供了可视化Animator视窗,可以直观地通过动画参数和Transition(动画过渡线)
等管理各个动画间的过度。

Mecanim动画系统常见术语
Animator (Mecanim动画系统组件)
AnimatorController 动画控制器(动画控制器资源相当于一个容器,我们可以通过创建多个动画节点,并形成动画状态机,来处理各个动画之间的过度以及播放逻辑)
Avatar(将角色的骨骼转换为Mecanim可识别的骨骼)
Retargeting(角色之间动画的互用也可以说是动画重定向)

1.选择到模型源文件查看 在这里插入图片描述
2.将动画模式调整为Mecanim可识别样式 (人类,动画可以复用) (非人类,动画不能复用)在这里插入图片描述

Animation动画样式为 在这里插入图片描述
3. Apply应用到模型
4. 在这里插入图片描述 (若为对勾显示则骨骼匹配成功,若为叉号显示则需要重新匹配)
5. 创建在这里插入图片描述 在这里插入图片描述->给到角色上 在这里插入图片描述
6. 找到Window下Animator面板 将需要的动画拖到面板中即可
若出现匹配失败需要重新匹配点击 在这里插入图片描述->进入此界面 在这里插入图片描述
找到-> 在这里插入图片描述在这里插入图片描述
动画状态机动画切换
在这里插入图片描述
此颜色的动画状态,说明此动画为默认动画(此处跳舞为默认动画)

  1. 若想实现角色从待机切换到跳舞效果,先将待机动画拖拽到Animator面板(或者右键创建Empty,将右边属性motion选择待机动画)-> 将待机动画设置为默认动画(在待机动画状态右键选择 ) -> 待机动画即为默认动画 -> 在待机动画状态右键选择 ->
  2. 添加动画参数
  3. 选择动画过渡线设置条件 在这里插入图片描述

Mecanim BlendTree(混合树)
待机->跑0、左-1右1跑(水平轴)
(可实现一个动画状态有多个动画效果,如跑,既可以前跑也可以左右跑)
1.创建 BlendTree
在这里插入图片描述
2.双击blendTree动画状态
3.进入此界面,然后点击添加需要的动画 ->
注意在这里插入图片描述: 如果勾选则Threshold数值不能自己调整。在这里插入图片描述在这里插入图片描述在这里插入图片描述
如果需要调整则取消勾选即可。
设置为 在这里插入图片描述,此处想通过键盘平行轴返回值控制左右跑动画,则为-1 ,0, 1。在这里插入图片描述
添加AD小数,在BlendTree应用AD 在这里插入图片描述
Mecanim BlendTree 2D

在这里插入图片描述
通过2个动画参数控制动画切换
InputWS InputAD分别对应POSX 与POSY两个数值
在这里插入图片描述
在这里插入图片描述
Mecanim层设置,用于角色动画混合效果(如:边跑边攻击)
在这里插入图片描述点击此处添加层,可更改Name,通过Weight设置动画权重,Mask控制动画混合位置,并将此层需要的动画拖到面板中 。在这里插入图片描述
注意Mask 在这里插入图片描述 在Project视窗创建,选择 在这里插入图片描述
在这里插入图片描述此处为将腿遮罩,则腿不会播放dance动画,当调节Weight动画权重数值时可看到融合效果(范围从0~1),1为完全融合。

Weight 权重
	权重是指某个动画层在整个动画中的影响,
	若权重值为1则此层动画将与整个动画融合
	若权重值为0则此层动画与整个动画完全不融合

动画事件
找到角色源文件->找到需要的动画-> 在这里插入图片描述
在这里插入图片描述
此脚本给在角色上,当攻击动画将要播放完时调用AttackBool();
在这里插入图片描述
判断动画是否在播放

Animator anim ;
//默认层的待机动画 哈希值
	int idle = Animator.StringToHash("Base layer.Idle"); 
AnimatorStateInfo currentBaseStage;//当前播放的动画

	void Start () {
		anim = GetComponent<Animator>();
	}

	void Update () {
		currentBaseStage = anim.GetCurrentAnimatorStateInfo(0);//当前播放的动画
		if (currentBaseStage.nameHash == idle && !anim.IsInTransition(0))//正在播放待机动画,并且没有动画衔接(0)参数0表示默认层
		{
			anim.SetBool("hit", false);
		}

任意状态

using UnityEngine;
using System.Collections;

public class AnyStateTest : MonoBehaviour
{
    public float playerHP = 5;
    private Animator anim;
    private bool flag = true;
    private void Start()
    {
        anim = this.GetComponent<Animator>();
    }
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            if(playerHP>0)
            playerHP -= 1;
        }
        AnimFunc();
    }
    private void AnimFunc()
    {
        if (playerHP <= 0 && flag)
            anim.SetBool("DieBool", true);
    }
    /// <summary>
    /// 死亡动画最开始事件
    /// </summary>
    public void DieStart()
    {
        anim.SetBool("DieBool", false);
        flag = false;
    }
    /// <summary>
    /// 死亡动画最结束事件
    /// </summary>
    public void DieEnd()
    {
        Destroy(gameObject);
    }
}

脚本添加动画事件

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class AnimEvent : MonoBehaviour
    {
        private Animator anim = null;
        public int number = 0;
        private void Start()
        {
            anim = GetComponent<Animator>();
            //获取默认层播放的动画
            AnimatorClipInfo[] clipInfo = anim.GetCurrentAnimatorClipInfo(0);
            var animEvent = new AnimationEvent();
            //动画播放第5秒添加事件
            animEvent.time = 5;
            animEvent.functionName = "AnimEventFunc";
         
            clipInfo[0].clip.AddEvent(animEvent);
        }
        private void AnimEventFunc()
        {
            print((number++).ToString());
        }

    }```

猜你喜欢

转载自blog.csdn.net/jjjndk1314/article/details/84993357