【unity游戏开发入门到精通——动画篇】Animator反向动力学(IK)

考虑到每个人基础可能不一样,且并不是所有人都有同时做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篇大概率就不需要看了,节约学习时间成本。

文章目录

什么是反向动力学(IK)

一般我们都是通过父节点来调动子节点运动,而在实际开发过程中,有时候我们需要子节点带动父节点进行相应的动作。这种情况就是反向动力学

用我们人体举例子,当我们拿起一个杯子的时候是用手掌去拿,以杯子为参照物,我们移动杯子的位置,手臂会随着杯子一起移动。用父子骨骼理解的话就是子带动了父。

IK反向动力学控制对于我们的意义

  • 让我们的人物模型的胳膊一直指向某一个物体(在不需要动画的前提下),拾取某一件物品
  • 设置人物头部一直看向某个位置
  • 人物走路踩到了石头,就需要由脚的子节点带动全身骨骼做出踩到石头的响应
  • 例如刺客信条,手部带动身体的爬行
  • 比如跳跃到某个位置
  • 持枪或持弓箭瞄准某一个对象等

为什么能实现IK?

首先我们要知道人的模型是由以节点模型为基础搭建而成的,通过反向动力学,我们可以调动节点来实现人物模型的运动。

比如让手臂指向某一个物体a:我们调用反向动力学,使得手臂的手掌节点指向物体a,然后手掌节点调动关节节点再调用肩膀处的节点,实现整个手臂指向物体a。

如何进行IK控制

在状态机的层级设置中开启 IK 通道。

继承MonoBehavior的类中,Unity定义了一个IK回调函数:OnAnimatorIK,我们可以在该函数中调用Unity提供的IK相关API来控制IK。

csharp 复制代码
private void OnAnimatorIK(int layerIndex)
{
    // 在这里进行IK控制的代码
}

Animator中的IK相关API:

csharp 复制代码
// 设置头部IK权重
animator.SetLookAtWeight(1, 1f, 1f);
// 设置头部IK看向位置
animator.SetLookAtPosition(pos.position);
// 设置IK位置权重
animator.SetIKPositionWeight(AvatarIKGoal.RightFoot, 1);
// 设置IK旋转权重
animator.SetIKRotationWeight(AvatarIKGoal.RightFoot, 1);
// 设置IK对应的位置
animator.SetIKPosition(AvatarIKGoal.RightFoot, pos2.position);
// 设置IK对应的角度
animator.SetIKRotation(AvatarIKGoal.RightFoot, pos2.rotation);

简单的使用

游戏人物盯着某个游戏对象看,来达到时刻注视的效果。

创建一个位置变量来承接后面我们获取的要指向或看向的游戏物体的坐标

csharp 复制代码
//目标物体位置
public Transform target;

脚本绑定要看的物体

打开IK开关

游戏人物盯着某个游戏对象看,来达到时刻注视的效果

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

    // 特定方法 layerIndex:我们控制第几层的IK
    void OnAnimatorIK(int layerIndex)
    {
        //设置头部IK权重
        animator.SetLookAtWeight(1);
        //设置头部看向的位置
        animator.SetLookAtPosition(target.position);
    }
}

效果

更复杂一点,就是让身体右手也跟着注释的对象移动或摆动

csharp 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

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

    // 特定方法 layerIndex:我们控制第几层的IK
    void OnAnimatorIK(int layerIndex)
    {
        //设置头部IK权重
        animator.SetLookAtWeight(1);
        //设置头部看向的位置 后面还有
        animator.SetLookAtPosition(target.position);

        //设置右手IK
        animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 1);
        //设置右手旋转权重
        animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 1);
        //设置右手指向物体
        animator.SetIKPosition(AvatarIKGoal.RightHand, target.position);
        animator.SetIKRotation(AvatarIKGoal.RightHand, target.rotation);
    }
}

效果


专栏推荐

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

完结

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

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

相关推荐
weifexie23 分钟前
ruby可变参数
开发语言·前端·ruby
王磊鑫24 分钟前
重返JAVA之路-初识JAVA
java·开发语言
千野竹之卫24 分钟前
3D珠宝渲染用什么软件比较好?渲染100邀请码1a12
开发语言·前端·javascript·3d·3dsmax
liuluyang5301 小时前
C语言C11支持的结构体嵌套的用法
c语言·开发语言·算法·编译·c11
凌叁儿1 小时前
python保留关键字详解
开发语言·python
qq_428639612 小时前
虚幻基础:碰撞&帧运算
游戏引擎·虚幻
明飞19872 小时前
C_内存 内存地址概念
c语言·开发语言
代码不停2 小时前
Java中的异常
java·开发语言
兮兮能吃能睡3 小时前
Python中的eval()函数详解
开发语言·python
狄加山6753 小时前
Qt模型-视图架构
开发语言·qt