1. 程式人生 > >unity的Mecanim動畫系統

unity的Mecanim動畫系統

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

    }```