Unity动画匹配MatchTarget,让你的模型跳到高山之巅!

基于Animator.MatchTarget定点角色脚部位置,实现人物跳跃效果。本文章涉及人物移动控制,镜头跟随旋转控制,动画状态机,射线检测,动画匹配等功能。

一、最终效果

实现角色移动,镜头控制,动画
![简单的跳跃](https://img-blog.csdnimg.cn/ebd3322cf8be446b9cacdb7473dddf99.gif
这里限制了高度,不过没有限制,将会是这样的!
在这里插入图片描述

二、关键Api

因为这次的动画需要匹配脚部最终的落点位置,我们需要用到animator的MatchTarget方法。
unity的官方手册中有这个api的详细用法,在这里也详细介绍

MatchTarget(
	Vector3 matchPosition, //需要匹配的点位置
	Quaternion matchRotation, //匹配点的旋转 这里一般设置为Quaternion.identity
	//匹配的部位 这里是某个身体部位 该demo中用的是LeftFoot 把脚部匹配过去 如果是攀爬的可以使用LeftHand这种部位也是同理的
	AvatarTarget targetBodyPart, 
	//这里包含了需要匹配的权重信息 包含xyz坐标 默认为Vecter3.one,旋转为0
	MatchTargetWeightMask weightMask, 
	//最后两个参数是匹配开始和结束的归一化时间,这里表面动画播放到这个位置开始匹配动画的位置和旋转信息,在结束的时候就会到达指定的位置
	float startNormalizedTime, //这里是匹配开始的动画时间
	[Internal.DefaultValue("1")] float targetNormalizedTime//匹配的结束时间
);

三、制作demo流程

1.资源来源

全部都是AssetStore上的免费资源,可以选择需要的模型和场景,自己导入。
动画是来源于https://www.mixamo.com/,这是一个可以给模型绑定动画到处的网站,非常实用。
你可以在这个网站中上传模型fbx文件,然后选择动作导出下载
在这里插入图片描述

2.动画导入

选择你想要的动画,然后导出fbx下载,注意要去掉皮肤,这样只会导出动画文件。
在这里插入图片描述
导入的fbx文件,选中里面的anim文件Ctrl+D就会拷贝一份出来,只需要这个文件即可,里面有些动作会带有位移信息,可以在anim中删除
在这里插入图片描述

3.动画状态机

里面涉及到人物移动和跳跃,新建的状态机Animator比较简单,配置好触发器
在这里插入图片描述
一些动画之间的过渡,需要把这个勾去掉,这样在触发状态变化的时候,可以马上切换到下一个动画,不会等待当前动画播放完成,这样可以达到马上切换的效果。
在这里插入图片描述

4.镜头移动

镜头移动比较简单,这里只需要在LateUpdate中更新相机的位置即可。

public class CameraControl : MonoBehaviour
{
    public Transform follow;
    private Vector3 camOffset = Vector3.zero;
    public float mouseScrollScale = -10;
    void Start()
    {
        camOffset = transform.position - follow.position;//先获取初始的偏移offset
    }

    private void Update()
    {
        if (Mathf.Abs(Input.GetAxis("Mouse ScrollWheel")) > 0)
        {
            Camera.main.fieldOfView = Camera.main.fieldOfView + Input.GetAxis("Mouse ScrollWheel") * mouseScrollScale;
        }
    }

    private void LateUpdate()
    {
        var mouse_x = Input.GetAxis("Mouse X");//获取鼠标X轴移动
        var mouse_y = -Input.GetAxis("Mouse Y");//获取鼠标Y轴移动
        if (Input.GetMouseButton(1))
        {
            transform.RotateAround(follow.position, Vector3.up, mouse_x * 5);
            transform.RotateAround(follow.position, transform.right, mouse_y * 5);
            camOffset = transform.position - follow.position;
        }
        transform.position = follow.position + camOffset;//相机位置为跟随物体的位置+偏移
    }
}

5.人物移动

人物移动需要获取键盘的输入,然后在每帧更新位置,同时更新animator的状态

moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
//以相机的方向 方便旋转相机
moveDirection = camTrans.TransformDirection(moveDirection);
moveDirection.y = 0;
if (moveDirection != Vector3.zero)
{
    //移动人物 下一帧的位置即为当前位置+方向*速度*增量时间 即为需要移动到的位置
    var nextPos = transform.position + moveDirection.normalized * speed * Time.deltaTime;
    transform.position = Vector3.Lerp(transform.position, nextPos, lerpDelta * Time.deltaTime);
    //控制人物转向
    transform.forward = Vector3.Lerp(transform.forward, moveDirection.normalized, lerpDelta * Time.deltaTime);
    animator.SetBool("Run", true);
}
else
{
    animator.SetBool("Run", false);
}

6.人物跳跃

在按下跳跃按钮的时候,我们需要知道前面是否有可以跳上的平台。
这里利用的射线检测,在大概小腿部的位置发出一条射线,根据检测到的目标取得平台的高度。
取得的平台高度,可以从碰撞盒的大小得出,这样就可以拿到人物最终的落脚位置

var distance = 2.0f;
var origin = transform.position + Vector3.up * 0.3f;
Physics.Raycast(origin, transform.forward, out hit, distance)
var targetSize = hit.collider.bounds.size;
matchTarget = hit.point;
matchTarget.y = targetSize.y;//高度和物体的高度相同

最后触发跳跃动画

animator.SetTrigger(JumpStateName);//播放跳起的动画

拿到匹配点后,在非过渡期间,调用MatchTarget方法

private void ProcessJump()
{ 
     if (animator.IsInTransition(0)) return;//非过渡状态才开始匹配
     if (IsAnim(JumpStateName))
     {
         animator.MatchTarget(matchTarget, Quaternion.identity, AvatarTarget.LeftFoot, new MatchTargetWeightMask(Vector3.one, 0), 0.28f, 0.55f);
     }
 }

具体参数可以从动画中取得,当人物开始起跳的时间,和跳跃完成的时间,这里根据不同的动画进行微调。
在这里插入图片描述

四、总结

可以用这个方法,在动画播放的同时移动,然后达到目标点。同理,这个可以用来实现攀爬跨越系统。
本次案例的工程在百度云分享:
链接:https://pan.baidu.com/s/1322_yIC6f3d4V7PCyV0P6Q
提取码:3u96

最后点赞关注评论三连哦!

  • 17
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

漫步云巅Kim

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值