После небольшого проб и ошибок, я верю, что достиг ответа.У меня были проблемы с осью вращения.Используя текущий код, он не может найти плоскость XY (ту же плоскость, на которой были расположены игровые объекты).Я загрузил на GitHub upload текущую версию.
Чтобы исправить код в вопросе, сначала я изменил две ключевые области:
float angleA = Vector3.Angle(joints[0].transform.up, (joints[1].transform.position - joints[0].transform.position).normalized);
float angleB = Vector3.Angle((joints[1].transform.position - joints[0].transform.position).normalized, (joints[2].transform.position - joints[1].transform.position).normalized);
float angleC = Vector3.Angle((joints[2].transform.position - joints[1].transform.position).normalized, (joints[3].transform.position - joints[2].transform.position).normalized);
на:
float angleA = calculateAngle(Vector3.up, joints[1].transform.position, joints[0].transform.position);
float angleB = calculateAngle(Vector3.up, joints[2].transform.position, joints[1].transform.position);
float angleC = calculateAngle(Vector3.up, joints[3].transform.position, joints[2].transform.position);
...
}
private float calculateAngle(Vector3 axis, Vector3 pos1, Vector3 pos2)
{
float value = 0f;
value = Vector3.Angle(axis, (pos1 - pos2).normalized);
Vector3 cross = Vector3.Cross(axis, (pos1 - pos2).normalized);
if (cross.z < 0)
value = -value;
return value;
}
Второй, чтобы изменить код в методе GetJacobianTranspose () с:
private float[,] GetJacobianTranspose() {
Vector3 J_A = Vector3.Cross(joints[0].transform.up, (joints[joints.Length - 1].transform.position - joints[0].transform.position));
Vector3 J_B = Vector3.Cross((joints[1].transform.position - joints[0].transform.position), (joints[joints.Length - 1].transform.position - joints[1].transform.position));
Vector3 J_C = Vector3.Cross((joints[2].transform.position - joints[1].transform.position), (joints[joints.Length - 1].transform.position - joints[2].transform.position));
...
на:
private float[,] GetJacobianTranspose() {
Vector3 J_A = Vector3.Cross(joints[0].transform.forward, (joints[joints.Length - 1].transform.position - joints[0].transform.position));
Vector3 J_B = Vector3.Cross(joints[1].transform.forward, (joints[joints.Length - 1].transform.position - joints[1].transform.position));
Vector3 J_C = Vector3.Cross(joints[2].transform.forward, (joints[joints.Length - 1].transform.position - joints[2].transform.position));
...
Использование соединений[i] .transform.forward используется для определения оси вращения, по которой звенья будут перемещаться в направлении целевого положения, что позволяет определить IK для плоскости XY.