Unity Animator动画状态机 深入理解(二)IK控制
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控制的更多相关文章
- Unity Animator动画状态机 深入理解(一)
接触Unity以来就已经有了Animator,Animation用的少,不过也大概理解他俩之间的一个区别于联系. 图中其实就是Animator和Animation之间的区别于联系了,啊!你肯定会告诉我 ...
- Unity Animator动画状态机 深入理解(三)二维混合树
介绍二维之前,先说说一维吧~ 这个是通过旋转角度速度快慢来表现身体的大转和中转~ 通过一个-133~133的数值来进行控制. 注:后面的那个对钩是镜像的意思. 其实二维混合树并没有想象中的那么难.先来 ...
- Animator动画状态机的简单使用
一.动画状态机的使用 1.动画状态机说明 2.动画切换箭头的Inspector面板 3.动画的Inspector面板 二.动画状态机的使用和脚本控制 1.动画状态机的使用 2.动画状态机的控制脚本 ...
- Unity3D中通过Animator动画状态机获取任意animation clip的准确播放持续时长
Unity3d 4及之前的版本中动画的播放用的animation,可直接获取其播放持续长度.但5.x及以后的版本中都是用animator来播放动画了. https://docs.unity3d.com ...
- Unity动画知识之二:Animator动画状态机
上次我们讲过Unity游戏动画从入门到住院,今天我们来讲一下动画状态机. 好了,现在我们已经成功的导入了动画.接下来要玩的东西就很装13啦.因为大部分动画师是用不到这家伙的,需要掌握这个技能的,至少也 ...
- 用Unity的Animation播放Animator动画Clip
简单的动画,其实不需要Animator动画状态机管理,用Animation播放效率更高,但可能由于历史遗留问题,或网上下载的第三方资源,得到的是Animator资源,可以在Clip的Debug试图下, ...
- unity 对Animator动画系统的研究
unity的新动画系统叫Mecanim,使用Animator来取代旧系统Animation,按Unity文档的惯例:知识点主要分2部分:unity manual和unity script,读者可以边看 ...
- Unity插件 - MeshEditor(六) 变形动画状态机
变形动画状态机--MeshAnimator,是针对MeshAnimation的状态管理器,有大量类似Unity animator的功能,但MeshAnimator操作会更加简便,更加直观,居家旅(zh ...
- 【转】unity Animator 怎么判断一个动画播放结束
关于unity Animator 怎么判断一个动画播放结束这里有几种方法.希望对大家有帮助.还有其他办法的可以分享一下 第一种方法:在动画结束帧后面加个动画事件,调用下含这个变量的函数接口不是可以了? ...
随机推荐
- 设计模式之单例模式的简单demo
/* * 设计模式之单例模式的简单demo */ class Single { /* * 创建一个本类对象. * 和get/set方法思想一样,类不能直接调用对象 * 所以用private限制权限 * ...
- 通过CSS的border绘制三角形
通过css的border 可以绘制出三角形, 不同的样式组合,有着不同的效果,可以控制它的大小,颜色,方向.看下面各种图形,相信可能还有很多图形,大家都没见过. 先写出公共的样式: .border { ...
- 使用 Vue 2.0 实现服务端渲染的 HackerNews
Vue 2.0 支持服务端渲染 (SSR),并且是流式的,可以做组件级的缓存,这使得极速渲染成为可能.同时, 和 2.0 也都能够配合 SSR 提供同构路由和客户端 state hydration.v ...
- 浅谈时钟的生成(js手写代码)
在生成时钟的过程中自己想到布置表盘的写法由这么几种: 当然利用那种模式都可以实现,所以我们要用一个最好理解,代码有相对简便的方法实现 1.利用三角函数 用js在三角函数布置表盘的过程中有遇见到这种情况 ...
- Atitit 自然语言处理原理与实现 attilax总结
Atitit 自然语言处理原理与实现 attilax总结 1.1. 中文分词原理与实现 111 1.2. 英文分析 1941 1.3. 第6章 信息提取 2711 1.4. 第7章 自动摘要 3041 ...
- 关于jni编译32位、64位动态库(Android.mk和Application.mk文件)
最近新项目需要编译64位的动态库,这里记录如何配置. 在jni目录下加入Android.mk和Application.mk文件. Application.mk APP_ABI := armeabi a ...
- ActionBar设置自定义setCustomView()留有空白的问题
先来看问题,当我使用ActionBar的时候,设置setCustomView时,会留有空白的处理 网上很多朋友说可以修改V7包到19,结果处理的效果也是不理想的. 下面贴出我觉得靠谱的处理代码 pub ...
- iOS开发系列--无限循环的图片浏览器
--UIKit之UIScrollView 概述 UIKit框架中有大量的控件供开发者使用,在iOS开发中不仅可以直接使用这些控件还可以在这些控件的基础上进行扩展打造自己的控件.在这个系列中如果每个控件 ...
- IO流总结
IO流的作用:用于设备和设备之间的数据传输. IO流的概念:流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象. IO流的分类: 按照操作数据的类型分为两种: 字节流和字符流. 按 ...
- SQL Server 2016 JSON原生支持实例说明
背景 Microsoft SQL Server 对于数据平台的开发者来说越来越友好.比如已经原生支持XML很多年了,在这个趋势下,如今也能在SQLServer2016中使用内置的JSON.尤其对于一些 ...