【unity游戏开发入门到精通——动画篇】Animator动作目标匹配MatchTarget函数的使用

考虑到每个人基础可能不一样,且并不是所有人都有同时做2D、3D开发的需求,所以我把 【零基础入门unity游戏开发】 分为成了C#篇、unity通用篇、unity3D篇、unity2D篇

  • 【C#篇】:主要讲解C#的基础语法,包括变量、数据类型、运算符、流程控制、面向对象等,适合没有编程基础的同学入门。
  • 【unity通用篇】:主要讲解unity的基础通用的知识,包括unity界面、unity脚本、unity资源管理、unity动画、unity摄像机等,适合unity初学者入门。
  • 【unity3D篇】:主要讲解unity3D的知识,unity3D角色、unity3D物理系统、unity3D光照等,适合只想做2D游戏的开发者学习。
  • 【unity2D篇】unity2D篇:主要讲解unity2D的知识,包括unity2D角色、unity2D物理系统、unity2D光照等,适合只想做3D游戏的开发者学习。

这样方便大家按需选择性的去学习,比如有编程基础的大概率可以直接从unity通用篇开始入门,没有编程基础的建议从C#篇开始学习。只想做2D游戏的话,可以直接从unity2D篇开始学习,3D篇大概率就不需要看了,节约学习时间成本。

一、前言

1、动画目标匹配核心原理

  • 核心价值:让角色动画的关键部位(手/脚)与场景物体精确对齐,解决动态环境中的动作适配问题

  • 典型应用场景

    • 跨越不同高度的平台

    • 攀爬梯子时手部抓握位置

    • 翻越障碍物时的落脚点

    • 特技动作的精准着陆

2、如何实现动画目标匹配

Unity中的Animator提供了对应的MatchTarget函数来完成该功能。自动调整 GameObject 的位置和旋转。

扫描二维码关注公众号,回复: 17625489 查看本文章
animator.MatchTarget(targetPos.position, targetPos.rotation, AvatarTarget.RightFoot, new MatchTargetWeightMask(Vector3.one, 1), 0.4f, 0.64f);
  • 参数一:目标位置
  • 参数二:目标角度
  • 参数三:匹配的骨骼位置
  • 参数四:位置和角度权重
  • 参数五:开始位移动作的百分比 这个参数要观察起跳瞬间动画播放了百分之多少
  • 参数六:结束位移动作的百分比 这个参数要观察落地瞬间动画播放了百分之多少

3、动画目标匹配注意事项

  • 必须保证动画已经切换到了目标动画上。
  • 必须保证调用时动画并不是处于过度阶段而真正在播放目标动画。
  • 需要开启animaotor组件的Apply Root Motion。
    在这里插入图片描述

二、完整实现流程(以跳跃为例)

1、前期准备

[Header("跳跃参数")]
public Transform targetPos; // 目标落点
public Animator animator;
private bool isJumping = false;

void Update()
{
    
    
    if (Input.GetKeyDown(KeyCode.Space) && !isJumping)
    {
    
    
        isJumping = true;
        animator.SetTrigger("Jump");
        StartCoroutine(WaitForTransition());
    }
}

2、精确触发匹配(协程方案)

IEnumerator WaitForTransition()
{
    
    
    // 等待直到进入Jump动画状态
    while (!animator.GetCurrentAnimatorStateInfo(0).IsName("Jump"))
    {
    
    
        yield return null;
    }
    
    // 获取动画标准化时间
    AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);
    float transitionTime = stateInfo.normalizedTime;

    // 在动画开始后0.1秒执行匹配(防止初始过渡抖动)
    yield return new WaitUntil(() => 
        stateInfo.normalizedTime >= 0.1f);

    ExecuteMatchTarget();
}

void ExecuteMatchTarget()
{
    
    
    animator.MatchTarget(
        targetPos.position, 
        targetPos.rotation,
        AvatarTarget.RightFoot,
        new MatchTargetWeightMask(new Vector3(1,1,1), 0.8f), // 位置权重全开,旋转权重80%
        0.35f,  // 开始匹配时间(动画35%处)
        0.68f   // 结束匹配时间(动画68%处)
    );
}

3、动画事件回调(双保险机制)

由于Idle动画切换到跳跃动画的时候存在过渡效果,过渡的时候直接用目标匹配会出现异常。
可以写一个函数在动画文件中绑定事件。

// 在Animation窗口添加关键帧事件
public void MatchTarqet()
{
    
    
    if (!isJumping) return;
    ExecuteMatchTarget();
}

在这里插入图片描述

三、实战:控制角色跳跃到某个位置

新增跳跃动画
在这里插入图片描述开启animaotor组件的Apply Root Motion。
在这里插入图片描述

代码控制人物跳跃到1,1,1点

public class ManScript : MonoBehaviour
{
    
    
    //目标物体位置
    public  Transform target;
    private Animator animator;
    
    void Start()
    {
    
    
        animator = GetComponent<Animator>();
    }

    void Update()
    {
    
    
        //播放起跳动画
        if (Input.GetKeyDown(KeyCode.Space))
        {
    
    
            animator.SetBool("Jump", true);
        }

        if (animator.IsInTransition(0)) return;//非过渡状态才开始匹配
        //获取第一图层动画
        AnimatorStateInfo info = animator.GetCurrentAnimatorStateInfo(0);
        //判断动画是否是跳跃动画
        if (info.IsName("Jump01"))
        {
    
    
            animator.SetBool("Jump", false);
            //跳跃
            // 第一个参数动作位置,第二个参数角色旋转,第三个是做动作的某个身体部位,第四个是权重信息,第五六参数是获取动画曲线
            animator.MatchTarget(new Vector3(1, 1, 1), Quaternion.identity, AvatarTarget.LeftFoot, new MatchTargetWeightMask(Vector3.one, 0),  0.25f, 0.57f);
        }
    }
}

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


专栏推荐

地址
【零基础入门unity游戏开发——C#篇】
【零基础入门unity游戏开发——unity通用篇】
【零基础入门unity游戏开发——unity3D篇】
【零基础入门unity游戏开发——unity2D篇】
【制作100个Unity游戏】
【推荐100个unity插件】
【实现100个unity特效】
【unity框架/工具集开发】

完结

好了,我是向宇,博客地址:https://xiangyu.blog.csdn.net,如果学习过程中遇到任何问题,也欢迎你评论私信找我。

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!
在这里插入图片描述