Unity3D学习笔记(十五):Animation旧动画

 
 
animator(新动画系统):骨骼动画,骨骼驱动,格式化编辑,动画机图形化
animation(旧动画系统):物理系统,帧动画
一、如何建立动画文件 Animation Clip
手动添加动画
1、添加animation
旧动画和新动画Clips文件的区别:
旧动画,设置少
运动模式:
----Once:动画播放完毕,再次调用可以播放
----Clamp Forever:永远一次
----Loop:从新开始
----PingPong:从尾再到头
新动画,设置多
----Loop Time循环
Debug设置:
旧动画默认勾选,新动画默认不勾选,如果旧动画想在新动画系统播放,新动画系统也需要勾选
2、建立动画片段
Ctrl+6快速打开
3、添加关键帧
代表播放后的帧偏移(播放后多少帧发生什么动作),不代表游戏时间

旧动画系统:需要用代码来驱动Animation

自动添加动画,红色按钮

二、使用Animation组件来播放Clip
一个物体有多个动画状态,用代码切换动画状态,动画帧的复用
在父物体上添加Animation,在子物体上录制动画帧(子物体保留父物体的属性,记录父物体局部坐标系,不会记录世界坐标系)
把父物体生成预制体,预制体生成的新物体,动画不会受原坐标影响
动画片段的空间差异和时间差异
动画片段的播放,停止,融合
动画片段的切换:硬切和融合Crossfade
动画片段添加动画事件

能侦测同属一个物体身上的脚本方法

三、如何从模型文件提取动画文件Clip
1、如果有动画,Animation会有内容,关键帧表格,动画师会给出

2、旧动画,进入Rig,修改Legacy

3、添加片段:名字,起始帧,结束帧
选中相应的Clips可以播放片段
做好的片段的位置,在相应的模型文件目录下
不建议直接拖拽使用,建议提取出来,选中动画,按住Ctrl+D,可以独立出动画片段,仅对该类型模型有效(如果骨骼系统是同一系统,则可以复用)
 
用计时器控制Animation动画片段
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AnimationManager : MonoBehaviour {
    public GameObject prefs;
    private float curTime = 0;
    private float interval = 1.0f;
    void Update () {
        if (Time.time < 10)
        {
            curTime += Time.deltaTime;
            if (curTime >= interval)
            {
                Instantiate<GameObject>(prefs).transform.position = Vector3.right * Mathf.FloorToInt(Time.time);
                curTime = 0;
            }
        }
    }
}

用代码控制Animation动画片段

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AnimationChange : MonoBehaviour {
    public Animation anim;
    void Update () {
        if (Input.GetKeyDown(KeyCode.Q))
        {
            anim.Play("AnimationChangeMove");
        }
        if (Input.GetKeyDown(KeyCode.E))
        {
            anim.Play("AnimationChangeScale");
        }
        if (Input.GetKeyDown(KeyCode.S))
        {
            anim.Stop();
        }
    }
    void SayBig()
    {
        Debug.Log("变大了");
    }
    void SaySmall()
    {
        Debug.Log("变小了");
    }
}

递归树

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Tree : MonoBehaviour {
    public float size;
    public GameObject treeGo;
    public void CreateSelf()
    {
        if (size < 0.05f) return;//给递归添加限值
        for (int i = 0; i < 6; i++)
        {
            GameObject go = Instantiate<GameObject>(treeGo);
            go.transform.position = transform.position + transform.up * 5 * size;
            go.transform.rotation = transform.rotation;
            go.transform.rotation *= Quaternion.AngleAxis(Random.Range(0, 360), Vector3.up) * Quaternion.AngleAxis(Random.Range(-120, 120), Vector3.right);
            go.GetComponent<Tree>().size = size * 0.5f;
            go.transform.localScale = Vector3.one * size * 0.5f;
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerAnimation : MonoBehaviour {
    public Animation anim;
       // Use this for initialization
       void Start () {
              
       }
       
       // Update is called once per frame
       void Update () {
        //如果每帧检测到播放的是当前动画,则不会重复播放动画第一帧,会让动画继续播下去
        //anim.Play("Idle");
        if (Input.GetKeyDown(KeyCode.Alpha1))
        {
            anim.Play("Move");
        }
        if (Input.GetKeyDown(KeyCode.Alpha2))
        {
            anim.Play("Idle");
        }
        if (Input.GetKeyDown(KeyCode.Alpha3))
        {
            anim.Play("Death");
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum PlaySta
{
    Move,
    Idle,
    Death
}
public class PlayerControl : MonoBehaviour {
    public Animation anim;
    public PlaySta playSta;
    // Use this for initialization
    void Start () {
        playSta = PlaySta.Move;
    }
       
       // Update is called once per frame
       void Update () {
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        moveDir.x = h;
        moveDir.z = v;
        cd += Time.deltaTime;
        Action();
    }
    void Action()
    {
        switch (playSta)
        {
            case PlaySta.Move:
                Move();
                break;
            case PlaySta.Idle:
                Idle();
                break;
            case PlaySta.Death:
                Death();
                break;
        }
    }
    Vector3 moveDir;
    Vector3 lookPoint;
    RaycastHit hit;
    public float moveSpeed = 3;
    void Move()
    {
        anim.Play("Move");
        transform.position += moveDir * moveSpeed * Time.deltaTime;
        if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 100, 1 << 8))
        {
            lookPoint = hit.point;
            lookPoint.y = transform.position.y;
            transform.LookAt(lookPoint);
        }
        if (moveDir.magnitude < 0.01f)
        {
            playSta = PlaySta.Idle;
        }
    }
    void Idle()
    {
        anim.Play("Idle");
        if (moveDir.magnitude >= 0.01f)
        {
            playSta = PlaySta.Move;
        }
    }
    float cd;
    public void Damage()
    {
        cd = 0;
        playSta = PlaySta.Death;
    }
    void Death()
    {
        anim.Play("Death");
    }
    public void OnTriggerEnter(Collider other)
    {
        if (other.tag == "Monster")
        {
            if (cd > 0.5f)
            {
                Damage();
            }
        }
    }
}
抛异常的用法:
try:包含异常的语句
try不能单独使用,要搭配catch和finally使用
catch:捕获异常,可以填参数
catch(Exception e){},(Exception是所有异常的基类)
finally:最后都会执行,作为替补收尾工作,
无论如何都会执行,即使前面有return
结果:输出“捕获到了异常”,而“11111”不会输出

树BlendTree
在外边不能播动画
里面两层中心点偏移
只能改中间层

猜你喜欢

转载自www.cnblogs.com/ciaowoo/p/10363029.html
今日推荐