我是 Unity 的新手,我正在使用逆运动学做一个项目,一方面(用手指),我正在接收硬件旋转数据(四元数),如果我唯一的输入是如何移动我的手指是旋转,最后一个手指上的四元数,手腕上的另一个!我在这里使用 Dogzer 的反向运动学示例链接!
这里 我的目标手指的图像在远端手指上,我想仅使用ROTATION计算其他手指的角度。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class InverseKinematics : MonoBehaviour {
public Transform upperArm;
public Transform forearm;
public Transform hand;
public Transform elbow;
public Transform target;
[Space(20)]
public Vector3 uppperArm_OffsetRotation;
public Vector3 forearm_OffsetRotation;
public Vector3 hand_OffsetRotation;
[Space(20)]
public bool handMatchesTargetRotation = true;
[Space(20)]
public bool debug;
float angle;
float upperArm_Length;
float forearm_Length;
float arm_Length;
float targetDistance;
float adyacent;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void LateUpdate () {
if(upperArm != null && forearm != null && hand != null && elbow != null && target != null){
upperArm.LookAt (target, elbow.position - upperArm.position);
upperArm.Rotate (uppperArm_OffsetRotation);
Vector3 cross = Vector3.Cross (elbow.position - upperArm.position, forearm.position - upperArm.position);
upperArm_Length = Vector3.Distance (upperArm.position, forearm.position);
forearm_Length = Vector3.Distance (forearm.position, hand.position);
arm_Length = upperArm_Length + forearm_Length;
targetDistance = Vector3.Distance (upperArm.position, target.position);
targetDistance = Mathf.Min (targetDistance, arm_Length - arm_Length * 0.001f);
adyacent = ((upperArm_Length * upperArm_Length) - (forearm_Length * forearm_Length) + (targetDistance * targetDistance)) / (2*targetDistance);
angle = Mathf.Acos (adyacent / upperArm_Length) * Mathf.Rad2Deg;
upperArm.RotateAround (upperArm.position, cross, -angle);
forearm.LookAt(target, cross);
forearm.Rotate (forearm_OffsetRotation);
if(handMatchesTargetRotation){
hand.rotation = target.rotation;
hand.Rotate (hand_OffsetRotation);
}
if(debug){
if (forearm != null && elbow != null) {
Debug.DrawLine (forearm.position, elbow.position, Color.blue);
}
if (upperArm != null && target != null) {
Debug.DrawLine (upperArm.position, target.position, Color.red);
}
}
}
}
void OnDrawGizmos(){
if (debug) {
if(upperArm != null && elbow != null && hand != null && target != null && elbow != null){
Gizmos.color = Color.gray;
Gizmos.DrawLine (upperArm.position, forearm.position);
Gizmos.DrawLine (forearm.position, hand.position);
Gizmos.color = Color.red;
Gizmos.DrawLine (upperArm.position, target.position);
Gizmos.color = Color.blue;
Gizmos.DrawLine (forearm.position, elbow.position);
}
}
}
}