IK还是一个很神奇和实用的东西啊,起码可以用代码来控制人物骨骼位置还是很爽的。因为不是动画师~

这篇可能跟Animator没啥关系了哈,都是代码层的。

看了一官方的案例,老的,有些问题,自己修改了一下,达到了效果。

官方建议把所有的IK操作放在OnAnimatorIK中进行。

如果我们要进行IK操作,先要绑定IK位置。IK能控制的官方都给了enum

 

然后我们要设置权重Weight,范围为0~1,这里都设成1

             avatar.SetIKPositionWeight(AvatarIKGoal.LeftFoot, 1.0f);
avatar.SetIKRotationWeight(AvatarIKGoal.LeftFoot, 1.0f);
avatar.SetIKPositionWeight(AvatarIKGoal.LeftHand, 1.0f);
avatar.SetIKRotationWeight(AvatarIKGoal.LeftHand, 1.0f);
avatar.SetIKPositionWeight(AvatarIKGoal.RightFoot, 1.0f);
avatar.SetIKRotationWeight(AvatarIKGoal.RightFoot, 1.0f);
avatar.SetIKPositionWeight(AvatarIKGoal.RightHand, 1.0f);
avatar.SetIKRotationWeight(AvatarIKGoal.RightHand, 1.0f);
avatar.SetLookAtWeight(1.0f, 0.3f, 1.0f, 0.5f);

如果我们把LeftFoot的权重设为0,则会出现以下情况

在官方给的脚本中IK的绑定并没有在OnAnimatorIK中,而放到了Update中,然后就出现了绑定失败的问题。

所以我把他们都放到了OnAnimatorIK中。就可以了。

关于IK的操作~,给的少。

     //设置右手IK位置
avatar.SetIKPosition(AvatarIKGoal.RightHand, rightHandObj.position);
//设置右手IK旋转
avatar.SetIKRotation(AvatarIKGoal.RightHand, rightHandObj.rotation);
//获取右手IK位置
rightHandObj.position = avatar.GetIKPosition(AvatarIKGoal.RightHand);
//获取右手IK旋转
rightHandObj.rotation = avatar.GetIKRotation(AvatarIKGoal.RightHand);

上完整代码~ (ikActive)没开启时球跟随人,开启时人跟随球。

 using UnityEngine;
using System.Collections; public class MyIK : MonoBehaviour { public Transform bodyObj = null;
public Transform leftFootObj = null;
public Transform rightFootObj = null;
public Transform leftHandObj = null;
public Transform rightHandObj = null;
public Transform lookAtObj = null;
private Animator avatar;
public bool ikActive = false; void Start()
{
avatar = GetComponent<Animator>();
} void OnAnimatorIK(int layerIndex)
{
if (avatar == null) return; if (ikActive)
{
avatar.SetIKPositionWeight(AvatarIKGoal.LeftFoot, 0.0f);
avatar.SetIKRotationWeight(AvatarIKGoal.LeftFoot, 1.0f);
avatar.SetIKPositionWeight(AvatarIKGoal.LeftHand, 1.0f);
avatar.SetIKRotationWeight(AvatarIKGoal.LeftHand, 1.0f);
avatar.SetIKPositionWeight(AvatarIKGoal.RightFoot, 1.0f);
avatar.SetIKRotationWeight(AvatarIKGoal.RightFoot, 1.0f);
avatar.SetIKPositionWeight(AvatarIKGoal.RightHand, 1.0f);
avatar.SetIKRotationWeight(AvatarIKGoal.RightHand, 1.0f);
avatar.SetLookAtWeight(1.0f, 0.3f, 1.0f, 0.5f); if (bodyObj != null)
{
avatar.bodyPosition = bodyObj.position;
avatar.bodyRotation = bodyObj.rotation;
} if (leftHandObj != null)
{
avatar.SetIKPosition(AvatarIKGoal.LeftHand, leftHandObj.position);
avatar.SetIKRotation(AvatarIKGoal.LeftHand, leftHandObj.rotation);
}
if (rightFootObj != null)
{
avatar.SetIKPosition(AvatarIKGoal.RightFoot, rightFootObj.position);
avatar.SetIKRotation(AvatarIKGoal.RightFoot, rightFootObj.rotation);
}
if (leftFootObj != null)
{
avatar.SetIKPosition(AvatarIKGoal.LeftFoot, leftFootObj.position);
avatar.SetIKRotation(AvatarIKGoal.LeftFoot, leftFootObj.rotation);
}
if (rightHandObj != null)
{
avatar.SetIKPosition(AvatarIKGoal.RightHand, rightHandObj.position);
avatar.SetIKRotation(AvatarIKGoal.RightHand, rightHandObj.rotation);
} if (lookAtObj != null)
avatar.SetLookAtPosition(lookAtObj.position);
}
else
{
if (bodyObj != null)
{
bodyObj.position = avatar.bodyPosition;
bodyObj.rotation = avatar.bodyRotation;
} if (leftFootObj != null)
{
leftFootObj.position = avatar.GetIKPosition(AvatarIKGoal.LeftFoot);
leftFootObj.rotation = avatar.GetIKRotation(AvatarIKGoal.LeftFoot);
} if (rightFootObj != null)
{
rightFootObj.position = avatar.GetIKPosition(AvatarIKGoal.RightFoot);
rightFootObj.rotation = avatar.GetIKRotation(AvatarIKGoal.RightFoot);
} if (leftHandObj != null)
{
leftHandObj.position = avatar.GetIKPosition(AvatarIKGoal.LeftHand);
leftHandObj.rotation = avatar.GetIKRotation(AvatarIKGoal.LeftHand);
} if (rightHandObj != null)
{
rightHandObj.position = avatar.GetIKPosition(AvatarIKGoal.RightHand);
rightHandObj.rotation = avatar.GetIKRotation(AvatarIKGoal.RightHand);
} if (lookAtObj != null)
{
lookAtObj.position = avatar.bodyPosition + avatar.bodyRotation * new Vector3(, 0.5f, );
}
avatar.SetIKPositionWeight(AvatarIKGoal.LeftFoot, );
avatar.SetIKRotationWeight(AvatarIKGoal.LeftFoot, );
avatar.SetIKPositionWeight(AvatarIKGoal.LeftHand, );
avatar.SetIKRotationWeight(AvatarIKGoal.LeftHand, );
avatar.SetIKPositionWeight(AvatarIKGoal.RightFoot, );
avatar.SetIKRotationWeight(AvatarIKGoal.RightFoot, );
avatar.SetIKPositionWeight(AvatarIKGoal.RightHand, );
avatar.SetIKRotationWeight(AvatarIKGoal.RightHand, );
avatar.SetLookAtWeight(0.0f);
}
} }

附一个彩蛋,IK有意思~~呵呵~ o(* ̄▽ ̄*)ブ

Unity Animator动画状态机 深入理解(二)IK控制的更多相关文章

  1. Unity Animator动画状态机 深入理解(一)

    接触Unity以来就已经有了Animator,Animation用的少,不过也大概理解他俩之间的一个区别于联系. 图中其实就是Animator和Animation之间的区别于联系了,啊!你肯定会告诉我 ...

  2. Unity Animator动画状态机 深入理解(三)二维混合树

    介绍二维之前,先说说一维吧~ 这个是通过旋转角度速度快慢来表现身体的大转和中转~ 通过一个-133~133的数值来进行控制. 注:后面的那个对钩是镜像的意思. 其实二维混合树并没有想象中的那么难.先来 ...

  3. Animator动画状态机的简单使用

    一.动画状态机的使用 1.动画状态机说明 2.动画切换箭头的Inspector面板 3.动画的Inspector面板 二.动画状态机的使用和脚本控制 1.动画状态机的使用  2.动画状态机的控制脚本 ...

  4. Unity3D中通过Animator动画状态机获取任意animation clip的准确播放持续时长

    Unity3d 4及之前的版本中动画的播放用的animation,可直接获取其播放持续长度.但5.x及以后的版本中都是用animator来播放动画了. https://docs.unity3d.com ...

  5. Unity动画知识之二:Animator动画状态机

    上次我们讲过Unity游戏动画从入门到住院,今天我们来讲一下动画状态机. 好了,现在我们已经成功的导入了动画.接下来要玩的东西就很装13啦.因为大部分动画师是用不到这家伙的,需要掌握这个技能的,至少也 ...

  6. 用Unity的Animation播放Animator动画Clip

    简单的动画,其实不需要Animator动画状态机管理,用Animation播放效率更高,但可能由于历史遗留问题,或网上下载的第三方资源,得到的是Animator资源,可以在Clip的Debug试图下, ...

  7. unity 对Animator动画系统的研究

    unity的新动画系统叫Mecanim,使用Animator来取代旧系统Animation,按Unity文档的惯例:知识点主要分2部分:unity manual和unity script,读者可以边看 ...

  8. Unity插件 - MeshEditor(六) 变形动画状态机

    变形动画状态机--MeshAnimator,是针对MeshAnimation的状态管理器,有大量类似Unity animator的功能,但MeshAnimator操作会更加简便,更加直观,居家旅(zh ...

  9. 【转】unity Animator 怎么判断一个动画播放结束

    关于unity Animator 怎么判断一个动画播放结束这里有几种方法.希望对大家有帮助.还有其他办法的可以分享一下 第一种方法:在动画结束帧后面加个动画事件,调用下含这个变量的函数接口不是可以了? ...

随机推荐

  1. 转 threejs中3D视野的缩放实现

    Threejs基础部分学习知道透视相机new THREE.PerspectiveCamera(fov, aspect , near,far)中. fov视野角(拍摄距离)越大,场景中的物体越小.fov ...

  2. 几句话就能让你理解:this、闭包、原型链

    以下是个人对这三个老大难的总结(最近一直在学习原生JS,翻了不少书,不少文档,虽然还是新手,但我会继续坚持走我自己的路) 原型链 所有对象都是基于Object.prototype,Object.pro ...

  3. dirname 命令

    dirname 命令用途将指定路径除了最后以外的部分写到标准输出.语法dirname Path描述dirname 命令读取指定路径名保留最后一个"/"(斜杠)及其后面的字符,删除其 ...

  4. SQL删除语句同时向备份表插入数据

    从这里摘抄下来的,觉得很不错,http://www.cnblogs.com/ljhdo/p/5792886.html#3503524 ,以后就用这种方式删除,再也不用担心删除错数据啦!!!

  5. 0037 Java学习笔记-多线程-同步代码块、同步方法、同步锁

    什么是同步 在上一篇0036 Java学习笔记-多线程-创建线程的三种方式示例代码中,实现Runnable创建多条线程,输出中的结果中会有错误,比如一张票卖了两次,有的票没卖的情况,因为线程对象被多条 ...

  6. xml类型使用注意事项

    xml 的数据类型在平常的开发也是很常用的,燃鹅.也是有一些地方需要留意.今天我就分享几个测试的例子. 使用 xquery.exist (有但不仅仅限于)的注意事项.通常使用来判断节点是否存在,值是否 ...

  7. iOS关于通知传值Bool类型的注意点

    比如: [[NSNotificationCenter defaultCenter] postNotificationName:@"Notification_Name" object ...

  8. 认识 EXT2 文件系统

    认识ext文件系统 硬盘组成与分割 文件系统特性 Linux 的 EXT2 文件系统(inode) 与目录树的关系 EXT2/EXT3 文件的存取与日志式文件系统的功能 Linux 文件系统的运行 挂 ...

  9. linux分区机制(MBR GPT)简介

  10. Java的初始化块、静态初始化块、构造函数的执行顺序及用途探究

    Java与C++有一个不同之处在于,Java不但有构造函数,还有一个”初始化块“(Initialization Block)的概念.下面探究一下它的执行顺序与可能的用途. 执行顺序 首先定义A, B, ...