简体   繁体   English

沿 y 轴旋转四元数

[英]Rotate in the y axis Quaternion

I am controlling an object's rotation with the function Quaternion.FromToRotation .我正在使用 function Quaternion.FromToRotation控制对象的旋转。 But unfortunately it is rotating in all 3 axes.但不幸的是,它在所有 3 个轴上旋转。 Can someone help me so I can rotate only in the y axis and x & z should not be affected?有人可以帮助我,所以我只能在 y 轴上旋转并且 x & z 不应该受到影响吗?

private Quaternion currentRot;
private Vector3 startPos;
private bool offsetSet;

public GameObject Ball;

void Update()
{
        SetOffsets();
 
        Vector3 closestPoint = Vector3.Normalize(transform.position - Ball.transform.position);
        robot.transform.rotation = Quaternion.FromToRotation(startPos, closestPoint) * currentRot;
    
}

void SetOffsets()
    {
        if (offsetSet)
            return;
 
        startPos = Vector3.Normalize(transform.position - Ball.transform.position);
        currentRot = Ball.transform.rotation;
 
        offsetSet = true;
    }

A different approach is needed.需要一种不同的方法。 Instead of keeping a direction to indicate your starting offset, keep a signed angle to the local forward from a particular direction related to the ball, rotated around the local up.与其保持一个方向来指示您的起始偏移量,不如保持与球相关的特定方向与局部前锋的有符号角度,围绕局部向上旋转。 That particular direction is the direction of the ball, projected on the plane normal to robot's up, or in other words, "flattened" so it is no longer locally above or below the robot.该特定方向是球的方向, 投影在垂直于机器人向上的平面上,或者换句话说,“展平”,因此它不再局部高于或低于机器人。

private Quaternion startRot; // currentRot is a misleading name
private float startAngleOffset;
private bool offsetSet;

[SerializeField] GameObject Ball;

void SetOffsets()
{
    if (offsetSet)
        return;
 
    Vector3 thisToBall = Ball.transform.position - transform.position;
    Vector3 robotUp = robot.transform.up;
    Vector3 flattenedToBall = Vector3.ProjectOnPlane(thisToBall, robotUp);
    Vector3 startAngleOffset = Vector3.SignedAngle(flattenedToBall, 
            robot.transform.forward, robotUp);
        
    currentRot = Ball.transform.rotation;
 
    offsetSet = true;
}

Then, when it comes time to set the rotation, do another projection of the ball's direction, then use this signed angle to find the direction forward should be .然后,当需要设置旋转时,对球的方向进行另一个投影,然后使用这个有符号的角度来找到向前的方向应该是 Then use Quaternion.LookRotation to set the rotation accordingly.然后使用Quaternion.LookRotation相应地设置旋转。

Altogether:共:

private Quaternion startRot;
private float startAngleOffset;
private bool offsetSet;

[SerializeField] GameObject Ball;

void Update()
{
    SetOffsets();

    Vector3 robotUp = robot.transform.up;
    Vector3 flattenedToBall = GetFlattenedToBall();
    Vector3 robotForwardDir = Quaternion.AngleAxis(startAngleOffset, robotUp)
            * flattenedToBall;

    robot.transform.rotation = LookRotation(robotForwardDir, robotUp);
}


void SetOffsets()
{
    if (offsetSet)
        return;
 
    Vector3 flattenedToBall = GetFlattenedToBall();
    Vector3 startAngleOffset = Vector3.SignedAngle(flattenedToBall, 
            robot.transform.forward, robot.transform.up);
    
    currentRot = Ball.transform.rotation;
 
    offsetSet = true;
}

Vector3 GetFlattenedToBall()
{
    Vector3 thisToBall = Ball.transform.position - transform.position;
    Vector3 flattenedToBall = Vector3.ProjectOnPlane(thisToBall, robot.transform.up);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM