• Unity---动画系统学习(5)---使用MatchTarget来匹配动画


    1. 介绍

    做好了走、跑、转弯后,我们就需要来点更加高级的动画了。
    我们使用自带动画学习笔记2中的翻墙Vault动画,来控制人物翻墙。


    在[动画学习笔记4](https://www.cnblogs.com/Fflyqaq/p/10777793.html)的基础上添加Vault动画。 ![](https://img2018.cnblogs.com/blog/1355434/201904/1355434-20190427134224868-1278682975.png) 添加一个参数**Vault**,设置当人物处于跑的状态并且Vault参数为true时会自动翻墙。 ![](https://img2018.cnblogs.com/blog/1355434/201904/1355434-20190427134439683-1900554000.png)

    2. 问题

    问题1:如何判断当人物跑向墙体时,在一定范围内触发跳跃动画?
    问题2:跳跃动画如果只是播放的话,很可能会出现穿模现象,如何让人物的手正好按着墙翻过去呢?

    2.1 问题1

    解决思路:

    1. 新建一个坐标用于存储跳跃时,手要按下的位置
    2. 判断人物是否处于跑的状态
    3. 使用射线检测,当人物正前方一段距离为要跳跃墙面时,获取此物体最上面的点为要按下的点

    下面新方法的介绍:
    anim.GetCurrentAnimatorStateInfo(0).IsName("LocalMotion"):判断当前播放的动画是否为LocalMotion动画,返回bool

    public static bool Raycast(Vector3 origin, Vector3 direction, out RaycastHit hitInfo,float maxDistance = Mathf.Infinity):射线起点,射线方向,碰撞物体信息,检测最大距离

    	private Animator anim;
    	private Vector3 matchTarget = Vector3.zero; //匹配手按下的位置
    
    	void Start () {
            anim = gameObject.GetComponent<Animator>();
    	}
    
    	void Update()
    	{
    		ProcessVault();
    	}
    
    	private void ProcessVault()
        {
            bool isVault = false;
            //只有物体在Blend Tree动画下才需要检测,0是层数,默认状态是第0层
            if (anim.GetFloat(speedZID) > 3 && anim.GetCurrentAnimatorStateInfo(0).IsName("LocalMotion"))
            {
                //射线起点,射线方向,碰撞物体信息,检测最大距离
                //起点在脚部向上一点,射线方向是人物正前方,
                RaycastHit hit;
                if (Physics.Raycast(transform.position + Vector3.up * 0.3f, transform.forward, out hit, 4.0f))
                {
    				//Obstacle是要跳跃墙面的tag
                    if (hit.collider.tag == "Obstacle")
                    {
                        //只有一定距离时才会触发,不然贴着墙走就会跳了
                        if (hit.distance > 3)
                        {
                            Vector3 point = hit.point;
                            //修改碰撞点y坐标为:碰撞体的y位置+碰撞体的尺寸高度
                            point.y = hit.collider.transform.position.y + hit.collider.bounds.size.y;
                            matchTarget = point;
    
                            isVault = true;
    
                        }
                    }
                }
            }
            anim.SetBool(valutID, isVault);
        }
    

    2.2. 问题2

    问题2的解决方法就要靠我们的MatchTarget了,上面获取了手要按下的点后,只需要让手按在这里就行了。

    anim.IsInTransition(0):该层动画是否在进行动画的过渡,返回bool

    void MatchTarget (Vector3 matchPosition, Quaternion matchRotation, AvatarTarget targetBodyPart, MatchTargetWeightMask weightMask, float startNormalizedTime,float targetNormalizedTime)
    参数1:要匹配点的位置。
    参数2:匹配的目标点旋转角度的四元数(不太懂,写Quaternion.identity)。
    参数3:要匹配的人物位置(AvatarTarget.LeftHand表示人物骨骼的左手)
    参数4:position和rotation占的权重(因为我们只匹配位置,所以如下设置位置权重1,旋转权重0)。
    参数5:从动画的什么时候开始匹配。
    参数6:什么时候结束(这需要自己慢慢调试,多试试就好了)

    	private void ProcessVault()
        {
            if (anim.GetCurrentAnimatorStateInfo(0).IsName("Vault") && anim.IsInTransition(0) == false)
            {
                //当正为跳墙的状态时候触发
                anim.MatchTarget(matchTarget, Quaternion.identity, AvatarTarget.LeftHand, new MatchTargetWeightMask(Vector3.one, 0), 0.32f, 0.4f);
            }
        }
    
  • 相关阅读:
    android 68 单元测试
    android 67 生成和解析xml
    android 66 sharedperference的使用
    android 65 文件访问权限
    android 64 sd卡读写的操作
    EditText操作收集
    android Fragments详解六:处理fragement的生命周期
    Context
    android 63 Fragment
    在Centos安装oracle_11gR2进度68%"Error in invoking target mkldflags ntcontab.o nnfgt.o of makefile..”
  • 原文地址:https://www.cnblogs.com/Fflyqaq/p/10778608.html
Copyright © 2020-2023  润新知