家长轮换具体的孩子的位置和轮换

问题描述

我有一个只能在Y轴上旋转的字符,所以如果up是Vector3.up,则基本上是左右。角色有一个孩子,这是手榴弹产生的位置(他的右手),现在我试图弄清楚如何为父母计算正确的旋转角度,以便孩子准确地瞄准目标,但只能“水平地”瞄准目标。 ”。父级的x和z旋转必须为0。有没有办法做到这一点?如果孩子只在“水平平面”上朝着正确的方向看,而没有向上或向下看以完美面对目标,那很好。

这个答案几乎可以满足我的要求:http://answers.unity.com/comments/1339850/view.html

唯一的问题是,产生的旋转是所有三个轴的混合,而不仅仅是y旋转。

解决方法

Afaik,您只需要反转孩子的localEulerAngles.y

localEulerAngles是子项相对于父项以欧拉角偏移的旋转角度。因此,仅采用y组件已经可以告诉您孩子相对于其父级的偏移量。

所以我想为了将父级相应地旋转回去,例如,

// as usual get the direction from child to target
var targetDirection = targetObject.transform.position - childObject.transform.position;

// flatten the direction by erasing any difference in the Y-axis
var targetDirectionFlat = Vector3.Scale(new Vector3(1,1),targetDirection).normalized;

// get the Y angle offset between parent and child 
var offset = -childObject.transform.localEulerAngles.y;

// rotate the parent to face the flattened direction minus the offset
// both are rotations around the Y axis only
parent.transform.rotation = Quaternion.LookDirection(targetDirectionFlat) * Quaternion.Euler(Vector3.up * offset);

注意:我在智能手机上打字,但我希望这些想法能弄清楚

,

我将使用三角函数解决此问题。注释中的解释:

Vector3 rotAxis = Vector3.up;

// flatten child pos,target pos,char pos,and child forward.
Vector3 flatChildPos = Vector3.ProjectOnPlane(childTransform.position,rotAxis);
Vector3 flatTargetPos = Vector3.ProjectOnPlane(targetTransform.position,rotAxis);
Vector3 flatCharPos = Vector3.ProjectOnPlane(charTransform.position,rotAxis);
Vector3 flatChildForward = Vector3.ProjectOnPlane(childTransform.forward,rotAxis);

Vector3 flatCharToTarget = flatTargetPos-flatCharPos;
Vector3 flatChildToChar = flatCharPos-flatChildPos;

// Find the angle going from the direction of child to parent to the child's forward
// The sign will come in handy later
float childAngle = Vector3.SignedAngle(flatChildToChar,flatChildForward,rotAxis);
float absChildAngle = Mathf.Abs(childAngle);

// Find the distance between child and character:
float childDist = flatChildToChar.magnitude;

// Find the distance between character and target:
float targetDist = flatCharToTarget.magnitude;

// Consider the triangle made by character position,position of target,and
// desired child position. Use sin rule to find angle of target's corner
float targetAngle = Mathf.Rad2Deg * Mathf.Asin(
        Mathf.Sin(absChildAngle * Mathf.Deg2Rad)
        * childDist/targetDist);

// determine angle in parent's corner:
float desiredParentAngle = 180f - absChildAngle - targetAngle;

// Determine sign of angle at character from target to child. 
// It's the same as the sign of angle at child from char to target.
float sign = Mathf.Sign(childAngle);

// Consider the triangle made by character position,and 
// current child position. Determine the current signed angle in character corner.
float currentParentAngle = Vector3.SignedAngle(flatCharToTarget,-flatChildToChar,rotAxis);

// Calculate the diff in angle needed to make the current triangle the desired one.
float diffAngle = desiredParentAngle * sign - currentParentAngle;

// Apply the diff in world space
Quaternion newRot = Quaternion.AngleAxis(diffAngle,rotAxis) * charTransform.rotation;

有趣的是,在某些情况下,可能有两次旋转。确定是什么情况,以及第二轮旋转留给读者练习。提示:targetAngledesiredParentAngle有时也有多个有效值;)