新动画系统:
给模型选择动画类型
普通动画:Generic
人形动画:Humanoid
![Unity3D学习笔记(十六):Animator新动画_第1张图片](http://img.e-com-net.com/image/info8/91da33b72b394d46ba6a5b304a885b79.jpg)
建立动画控制器 - 在Project右击 - 选择Create-AnimatorContorller
将对应动画控制器拖入到Animator的Contorller
![Unity3D学习笔记(十六):Animator新动画_第2张图片](http://img.e-com-net.com/image/info8/737abbefdb364ee49ee7c4b18999cdda.jpg)
双击动画控制器可以打开Animator窗口
将对应动画片段拖入生成新节点,就可以编辑了
橙色节点:相当于旧动画系统的默认片段
灰色节点:
Any State:代表所有动画状态
![Unity3D学习笔记(十六):Animator新动画_第3张图片](http://img.e-com-net.com/image/info8/92341a2361af45c2946907b114f6afaa.jpg)
设置默认片段
建立基础连线
箭头代表两个动画的过渡
Transition Duration:代表融合
![Unity3D学习笔记(十六):Animator新动画_第6张图片](http://img.e-com-net.com/image/info8/06e33cff928e4e848d8387d7e92b2621.png)
任何状态都可以连线到death,甚至包括自己到自己
取消death过渡到自己的选择
动画鬼畜问题,自己过渡到自己
![Unity3D学习笔记(十六):Animator新动画_第7张图片](http://img.e-com-net.com/image/info8/d38c73a525e34e1498a3aa2eaa735dc2.jpg)
建立过渡条件
添加参数,有4种
通过代码激活参数,实现动画切换
![Unity3D学习笔记(十六):Animator新动画_第8张图片](http://img.e-com-net.com/image/info8/b00e7fb8a2044731bd87e91ae22312a8.jpg)
默认过渡条件:Has Exit Time,播放完当前动画才会进行到下一动画的过渡
有条件,取消勾选
无条件,默认勾选,跳跃,浮空
![](http://img.e-com-net.com/image/info8/c6f8e22286da4037b8a406e8b1a86c36.jpg)
给游戏物体添加脚本,控制参数的激活
代码不能越权:越过动画状态机设置的逻辑(动画连线)的权限
![Unity3D学习笔记(十六):Animator新动画_第9张图片](http://img.e-com-net.com/image/info8/a544f3e7a3b14a56809cc116a913a45c.jpg)
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().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 { ListbirthPoint; public GameObject[] monsterPreGo; //最大怪物数 public int MaxMonsterCount; public List monsterList; public NewPlayer player; // Use this for initialization void Start () { birthPoint = new List (); monsterList = new List (); //遍历所有的子物体,将其加到出生点列表中 for (int i = 0; i < transform.childCount; i++) { birthPoint.Add(transform.GetChild(i)); } } void CreateMonster() { monsterCont++; GameObject go; if (monsterCont%5==0) { go = Instantiate (monsterPreGo[1]); } else { //实例化一个怪物 go = Instantiate (monsterPreGo[0]); } //怪物的位置设置任意出生点 go.transform.position = birthPoint[Random.Range(0, birthPoint.Count)].position; //取得怪物脚本 NewMonsterBase monster = go.GetComponent (); //把怪物放到管理器列表里 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(); } }
怪物动画添加死亡检测事件
骨骼动画锁定:只允许动画控制器修改
在动画状态机的设置里,取消骨骼动画锁定
![Unity3D学习笔记(十六):Animator新动画_第11张图片](http://img.e-com-net.com/image/info8/07e0c41be0e84d7b88908f15f06a3716.jpg)
怪物添加碰撞体
新动画系统的新功能
融合树功能:一个和多个参数,来决定播放哪个动画
更改动画类型
![Unity3D学习笔记(十六):Animator新动画_第15张图片](http://img.e-com-net.com/image/info8/9447957632684a64b371d31223f0f18c.jpg)
动画和模型分开
拖拽模型生成预制体
添加动画控制器
任意窗口最大化:shift+空格
中键拖动,滚轮缩放
动画本身带有位移动画,根据实际情况决定
好处:过渡自然
坏处:代码不可控,代码强拉,会显得不自然
勾选动画自带的位移动画
![Unity3D学习笔记(十六):Animator新动画_第19张图片](http://img.e-com-net.com/image/info8/4bf14873bf344bbf873f3310cdffccdd.jpg)
建立三个动画的融合树
添加参数,保存键值,保证参数正确传递
![](http://img.e-com-net.com/image/info8/3f7c0a0c5a784845a20c46f189c99203.jpg)
右键新建 融合树
双击融合树,打开融合树窗口,右键可以再添加融合树
添加motion
第一列:默认融合区间0到1 ,三个动画过渡0,0.5,1
第二列:动画速度
默认融合区间均等分开,取消勾选,可自行修改
![Unity3D学习笔记(十六):Animator新动画_第22张图片](http://img.e-com-net.com/image/info8/4971ec7daff2413a8885e9d84d970ea9.png)
旧动画系统修改动画片段的速度
添加脚本
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参数