本文章内容来自【uinty逆运动学-机械臂动画1/2】 https://www.bilibili.com/video/BV1e8411z7Li/?share_source=copy_web&vd_source=c41752496c26208e08a172a2410eecfe
为实现Unity 中机械臂的运动
我们先了解机械臂想要抓取到一个物体,抓点的位置和机械臂旋转角度的关系‘
图像斜率= (两点距离1-两点距离2)/(机器臂角度1-机械臂角度2)
这样得出的斜率有正负之分 具体怎么得可以看视频
用得出的斜率对机械臂进行旋转,从第一个机械臂旋转到最后一个机械臂
对机械臂进行设置时需要注意旋转节点需要是在旋转部件中心位置,并且需要绑定好父子级关系
对每个节点绑定Joint代码,并且设置子节点,设置好旋转轴
设置旋转轴时要注意旋转轴是对于物体的局部旋转,不是对于全局的
然后创建一个空物体命名为JXB_IKManager挂载脚本设置好根节点与末节点(是为抓手所在位置)
附代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class IKManger : MonoBehaviour
{
//根节点
public Joint m_root;
//子节点
public Joint m_end;
//目标点
public GameObject m_target;
public float m_threshold = 0.05f;
public float m_rate = 5.0f;
/// <summary>
/// 计算斜率
/// </summary>
/// <param name="_joint"></param>
/// <returns></returns>
float CalculateSlpoe(Joint _joint)
{
float deltaTheta = 0.01f;
float distance1 = GetDistance(m_end.transform.position, m_target.transform.position);
_joint.Rotate(deltaTheta);
float distance2 = GetDistance(m_end.transform.position, m_target.transform.position);
_joint.Rotate(-deltaTheta);
return (distance2 - distance1) / deltaTheta;
}
// Update is called once per frame
void Update()
{
if(GetDistance(m_end.transform.position,m_target.transform.position) > m_threshold)
{
Joint current = m_root;
while(current != null)
{
float slope = CalculateSlpoe(current);
current.Rotate(-slope * m_rate);
current = current.GetChild();
}
}
}
float GetDistance(Vector3 _point1,Vector3 _point2)
{
print(Vector3.Distance(_point1, _point2));
return Vector3.Distance(_point1, _point2);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum Hinge {
X,
Y,
Z
}
public class Joint : MonoBehaviour
{
public Hinge _Hinge;
public Joint m_child;
public Joint GetChild()
{
return m_child;
}
public void Rotate(float _angle)
{
if (_Hinge == Hinge.X)
{
transform.Rotate(Vector3.right * _angle);
}else if(_Hinge == Hinge.Y)
{
transform.Rotate(Vector3.up * _angle);
}else if(_Hinge == Hinge.Z)
{
transform.Rotate(Vector3.forward * _angle);
}
}
}