IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity动画匹配MatchTarget,让你的模型跳到高山之巅! -> 正文阅读

[游戏开发]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

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

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-09-11 19:08:27  更:2021-09-11 19:09:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 12:33:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码