刚开始学IK相关的内容,昨天看到一篇关于脚步IK的代码,啃了一个晚上总算是搞明白了,下面我就当作再温习一遍源代码
认识IK(Inverse Kinematics):
在unity3d中的人物动画中有十个位置的IK,分别是:头部,左右手掌,左右脚掌,左右膝关节,左右手肘关节
看到上面的那几个红球了吗,这些球就是在unity分析骨骼的时候生成的,我在别的up上面看到的解释是这样的: 是肢体本应该到达的位置
但是我的理解是:就拿脚部举例子,要实现反向动力学必须有一个运动的趋势,那么我的脚掌抬高了,膝盖应该怎么移动呢?对,就是向给定的IK位置移动,作为一个初学者我认为这样的理解方法是最适合我的,后期我也会慢慢学习并修缮我的理解
IK权重:
这个就比较好理解了,人物最初的动画都是按照动画的设计来的,所以权重是零,就不会收到IK的影响,相反的,如果权重越高,那个部位就会越靠近IK的部位,权重在(0,1)之间
上面的三个图中我将脚踝上的IK放到前面方便观察:
第一张图是权重等于零的时候可以看到动画还是按照原先的动画效果来
第二章图到了第三章图随着权重的增加脚踝的位置就慢慢向IK的位置靠近
IK相关函数:
大体上分为三类
一类是setIKposition(enum,vector3)来设置IK的位置
setIKrotation(enum,Quaternions)设置旋转
一类是setIkweight(enum,float(0-1))来设置权重
解读脚部IK代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Animator))]
public class IKSetting : MonoBehaviour
{
public bool enableFeetIk = true; //是否开启ik
[Range(0, 2)] [SerializeField] private float heightFromGroundRaycast = 1.2f; //从地面向上的cast距离
[Range(0, 2)] [SerializeField] private float raycastDownDistance = 1.5f; //向下cast 距离
[SerializeField] private LayerMask environmentLayer; //检测layer
[SerializeField] private float pelvisOffset = 0f; //盆骨offset
[Range(0, 1)] [SerializeField] private float pelvisUpAndDownSpeed = 0.28f; //盆骨赋值速度
[Range(0, 1)] [SerializeField] private float feetToIkPositionSpeed = 0.5f; //足IK赋值速度
public string leftFootAnimCurveName = "LeftFoot"; //权重曲线名称
public string rightFootAnimCurveName = "RightFoot"; //权重曲线名称
[Range(0, 100)] public float leftFootAngleOffset; //旋转偏移
[Range(0, 100)] public float rightFootAngleOffset; //旋转偏移
public bool useIkFeature = false; //是否使用IK旋转
public bool showSolverDebug = true;// Debug绘制
private Animator m_animator; //动画机
private Vector3 _rightFootPosition, _leftFootPosition; //足部骨骼posiition
private Vector3 _rightFootIkPosition, _leftFootIkPosition; //足部IK position
private Quaternion _leftFootIkRotation, _rightFootIkRotation; //足部IK rotation
private float _lastPelvisPositionY, _lastRightFootPositionY, _lastLeftFootPositionY; //上帧信息,用于lerp动画
#region for Gizmos
private Vector3 rightHitPoint;
private Vector3 leftHitPoint;
private bool flip = false;
#endregion
private void Start()
{
m_animator = GetComponent<Animator>();
}
private void FixedUpdate()
{
if (!enableFeetIk) return;
if (!m_animator) return;
AdjustFeetTarget(ref _rightFootPosition, HumanBodyBones.RightFoot); //