1. 程式人生 > >Unity3D學習筆記(十八):Animator新動畫

Unity3D學習筆記(十八):Animator新動畫

新節點 false 溝通 遍歷 模型生成 for in pan dha motion

新動畫系統: 給模型選擇動畫類型 普通動畫:Generic 人形動畫:Humanoid 技術分享圖片 建立動畫控制器 - 在Project右擊 - 選擇Create-AnimatorContorller 將對應動畫控制器拖入到Animator的Contorller 技術分享圖片 雙擊動畫控制器可以打開Animator窗口 將對應動畫片段拖入生成新節點,就可以編輯了 橙色節點:相當於舊動畫系統的默認片段 灰色節點: Any State:代表所有動畫狀態 技術分享圖片

設置默認片段

技術分享圖片

建立基礎連線

技術分享圖片

箭頭代表兩個動畫的過渡 Transition Duration:代表融合 技術分享圖片

任何狀態都可以連線到death,甚至包括自己到自己

技術分享圖片

取消death過渡到自己的選擇 動畫鬼畜問題,自己過渡到自己 技術分享圖片
建立過渡條件 添加參數,有4種 通過代碼激活參數,實現動畫切換 技術分享圖片

技術分享圖片

默認過渡條件:Has Exit Time,播放完當前動畫才會進行到下一動畫的過渡 有條件,取消勾選 無條件,默認勾選,跳躍,浮空 技術分享圖片 給遊戲物體添加腳本,控制參數的激活 代碼不能越權:越過動畫狀態機設置的邏輯(動畫連線)的權限 技術分享圖片

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HellephantAnimator : MonoBehaviour {
    public Animator anim;
       
// Use this for initialization void Start () { } // Update is called once per frame void Update () { if (Input.GetKeyDown(KeyCode.Alpha1)) { anim.SetBool("isMove", true); } if (Input.GetKeyDown(KeyCode.Alpha2)) { anim.SetBool(
"isMove", false); } if (Input.GetKeyDown(KeyCode.Alpha3)) { anim.SetTrigger("Death"); } } }
用一個怪物管理器,管理兩個怪物的父類 兩種方法: 1、管理兩個怪物的父類 2、把方法寫成接口 父類:全部寫成虛函數
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public enum EnemySta
{
    Move,
    Idle,
    Death
}
public class NewMonsterBase : MonoBehaviour {
    public PlayerControl moveTarget;//設置目標點
    public MonsterManager manager;//怪物屬於那個管理器
    public virtual void Action()
    {   
    }
    public virtual void Move()
    {      
    }
    public virtual void Idle()
    {       
    }
    public virtual void Damage()
    {      
    }
    public virtual void Death()
    {     
    }
    public virtual void DeathEvent()
    {    
    }
}

這兩個需要初始化,要放在父類裏

public PlayerControl moveTarget;//設置目標點
public MonsterManager manager;//怪物屬於那個管理器

子類:繼承父類,並重寫父類方法

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class HellephantControl : NewMonsterBase
{
    public Animator anim;
    public EnemySta enemySta;
    //因為我們需要經常用到目標的狀態,所以把TransForm改成了PlayerControl
    public NavMeshAgent navMeshAgent;//引用尋路系統
    private int enemyHealth = 30;//設置怪物生命值
    // Use this for initialization
    void Start()//子類添加新動畫系統
    {
        enemySta = EnemySta.Move;
        anim.SetBool("isMove", true);
    }
    // Update is called once per frame
    void Update()
    {
        Action();
    }
    public override void Action()
    {
        switch (enemySta)
        {
            case EnemySta.Move:
                Move();
                break;
            case EnemySta.Idle:
                Idle();
                break;
            case EnemySta.Death:
                Death();
                break;
        }
    }
    public override void Move()
    {
        //anim.CrossFade("Move", 0.2f);
        navMeshAgent.SetDestination(moveTarget.transform.position);
        //如果怪物的目標死了
        if (moveTarget.playSta == PlaySta.Death)
        {
            //尋路停止
            navMeshAgent.isStopped = true;
            //狀態切換到閑置
            enemySta = EnemySta.Idle;
            anim.SetBool("isMove", false);
        }
    }
    public override void Idle()
    {
        //anim.CrossFade("Idle", 0.2f);
    }
    public override void Damage()
    {
        //受傷減血
        enemyHealth -= 10;
        //Debug.Log("怪物生命"+enemyHealth);
        //如果血到了0
        if (enemyHealth <= 0)
        {
            //狀態變成死亡狀態
            enemySta = EnemySta.Death;
            anim.SetTrigger("Death");
            navMeshAgent.isStopped = true;
            gameObject.GetComponent<SphereCollider>().enabled = false;
            //gameObject.tag = "Untagged";
        }
    }
    public override void Death()//子類關閉老動畫系統
    {
        //anim.CrossFade("Death", 0.2f);
    }
    public override void DeathEvent()
    {
        //在管理器列表中移除自己
        manager.monsterList.Remove(this);
        //銷毀自己
        Destroy(this.gameObject);
    }
}
怪物管理器的怪物列表全部改成父類 怪物管理器的怪物生成 怪物預制體改成數組
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MounsterManager : MonoBehaviour {
    List<Transform> birthPoint;
    public GameObject[] monsterPreGo;
    //最大怪物數
    public int MaxMonsterCount;
    public List<NewMonsterBase> monsterList;
    public NewPlayer player;
       // Use this for initialization
       void Start () {
        birthPoint = new List<Transform>();
        monsterList = new List<NewMonsterBase>();
        //遍歷所有的子物體,將其加到出生點列表中
        for (int i = 0; i < transform.childCount; i++)
        {
            birthPoint.Add(transform.GetChild(i));
        }
     
    }
    void CreateMonster() {
        monsterCont++;
        GameObject go;
        if (monsterCont%5==0)
        {
            go = Instantiate<GameObject>(monsterPreGo[1]);
        }
        else
        {
            //實例化一個怪物
             go = Instantiate<GameObject>(monsterPreGo[0]);
        }
       
        //怪物的位置設置任意出生點
        go.transform.position = birthPoint[Random.Range(0, birthPoint.Count)].position;
        //取得怪物腳本
        NewMonsterBase monster = go.GetComponent<NewMonsterBase>();
        //把怪物放到管理器列表裏
        monsterList.Add(monster);
        //指定怪物的目標
        monster.moveTarget = player;
        //指定怪物的管理者
        monster.manager = this;
    }
    int monsterCont = 0;
    void CheckMonster() {
        if (monsterList.Count < MaxMonsterCount)
        {
            CreateMonster();
        }
    }
       // Update is called once per frame
       void Update () {
              
       }
    private void FixedUpdate()
    {
        CheckMonster();
    }
}

技術分享圖片

怪物動畫添加死亡檢測事件 骨骼動畫鎖定:只允許動畫控制器修改 在動畫狀態機的設置裏,取消骨骼動畫鎖定 技術分享圖片

技術分享圖片

技術分享圖片

怪物添加碰撞體

技術分享圖片

新動畫系統的新功能 融合樹功能:一個和多個參數,來決定播放哪個動畫 更改動畫類型 技術分享圖片

動畫和模型分開

技術分享圖片

拖拽模型生成預制體

技術分享圖片

添加動畫控制器

技術分享圖片

任意窗口最大化:shift+空格 中鍵拖動,滾輪縮放 動畫本身帶有位移動畫,根據實際情況決定 好處:過渡自然 壞處:代碼不可控,代碼強拉,會顯得不自然 勾選動畫自帶的位移動畫 技術分享圖片 建立三個動畫的融合樹 添加參數,保存鍵值,保證參數正確傳遞 技術分享圖片

右鍵新建 融合樹

技術分享圖片

雙擊融合樹,打開融合樹窗口,右鍵可以再添加融合樹

技術分享圖片

添加motion

技術分享圖片

第一列:默認融合區間0到1 ,三個動畫過渡0,0.5,1 第二列:動畫速度 默認融合區間均等分開,取消勾選,可自行修改 技術分享圖片

舊動畫系統修改動畫片段的速度

技術分享圖片

添加腳本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DefaultAvatarAnimator : MonoBehaviour {
    public Animator anim;
    public int speedHashID;
    public int angleHashID;
    public int attackHashID;
    private float slowSpeed;//速度修正
                            // Use this for initialization
    void Start () {
        speedHashID = Animator.StringToHash("Speed");//哈希Code,效能略高,不用每次調用都轉換
        angleHashID = Animator.StringToHash("Angle");
        attackHashID = Animator.StringToHash("Attack");
    }
    // Update is called once per frame
    void Update () {      
        if (Input.GetKey(KeyCode.LeftShift))
        {
            slowSpeed = 0.5F;
        }
        else
        {
            slowSpeed = 1.0F;
        }
        anim.SetFloat(speedHashID, Mathf.Clamp01(Input.GetAxis("Vertical")) * slowSpeed);//Mathf.Clamp01,剔除向後走的值
        anim.SetFloat(angleHashID, Input.GetAxis("Horizontal") * slowSpeed);
        if (Input.GetMouseButtonDown(0))
        {
            anim.SetTrigger(attackHashID);
        }      
       
    }
}

給Walk和Run添加融合樹

技術分享圖片

技術分享圖片

層級關系 兩個動畫融合,要和動畫師溝通,融合動作容易變形,最後讓動畫師手動新建動畫 邊跑動,邊射箭 添加Attack層,添加射箭節點,添加Attack參數 技術分享圖片

點擊齒輪,修改層級權重為1

技術分享圖片

Blending融合模式 Override,兩個動作折中,一般選則 Aaditive,兩個動作疊加 技術分享圖片 添加Avatar Mask,阿凡達遮罩 如果動畫類型是人形動畫:Humanoid,可選擇Humanoid的Mask 分配骨骼權重:點擊區域激活失活 動畫模型來自同一骨骼(同一Avatar) 技術分享圖片

添加代碼

技術分享圖片

Unity3D學習筆記(十八):Animator新動畫