【问题标题】:Unity3D Adjusting CUBE "endRotation" on right ( x or z) axisUnity3D在右(x或z)轴上调整CUBE“endRotation”
【发布时间】:2020-11-18 12:03:21
【问题描述】:

我是 Unity3D 脚本的新手,尤其是在涉及 Transform、Quaternions、Vector3 的细节方面。 下面有一个脚本。当我滚动立方体时,它会朝正确的方向翻转。但是,当立方体的本地轴与世界轴不匹配时,立方体的endRotation 会在错误的轴上执行。 谁能帮我解决这个问题:“endRotation” 会在右轴上翻转立方体,无论LOCAL axis <=> WorldAxis 之间的关系如何。 我试图解决它一个星期。因为没有成功。 再往下看代码和视频。

      if (Input.GetAxis("Horizontal") > buttonDown)
        {
            StartCoroutine(FlipTheCube(Vector3.right));
            return
        }...

。 . .

    public IEnumerator FlipTheCube(Vector3 direction)
{
    startFliping = false;

    float rollStartTime = 0;
    float rollAngle = 90;
    float halfWidth = transform.localScale.z / 2;
    Vector3 pointAround = transform.position + (Vector3.down * halfWidth) + (direction * halfWidth);
    Vector3 rollAxis = Vector3.Cross(Vector3.up, direction);

    Quaternion rotation = transform.rotation;
    Quaternion **endRotation** = rotation * Quaternion.Euler(rollAxis * rollAngle);
    Vector3 endPlacement = transform.position + direction;

    float oldAngle = 0;

    while (rollStartTime < rollDurtnTime)
    {
        yield return new WaitForEndOfFrame();
        rollStartTime += Time.deltaTime;
        float newAngle = (rollStartTime / rollDurtnTime) * rollAngle;
        float rotateThrough = newAngle - oldAngle;
        oldAngle = newAngle;

        transform.RotateAround(pointAround, rollAxis, rotateThrough);
    }

    transform.position = endPlacement;
    transform.rotation = **endRotation**;

    startFliping = true;
}

Here is a link to the youtube video First part of video If cubes local axis is matching world axis the "endRotation" is flipping correctly Second part of video as soon cubes local axis is not matching world axis "endRotation" goes wrong.

【问题讨论】:

    标签: c# unity3d quaternions


    【解决方案1】:

    您的问题在于以下几行:

    Vector3 rollAxis = Vector3.Cross(Vector3.up, direction);
    
    Quaternion rotation = transform.rotation;
    Quaternion endRotation = rotation * Quaternion.Euler(rollAxis * rollAngle);
    
    // ...
    
        transform.RotateAround(pointAround, rollAxis, rotateThrough);
    

    第一个问题是欧拉与角度/轴的使用。

    如果您只是针对Vector3.rightVector3.forward 和他们的负面因素进行轮换,您可能还没有注意到这一点。

    在第一部分中,您使用rollAxis 作为欧拉角表示,在第二部分中作为轴。

    问题在于,对于旋转,其轴通常与与该旋转的欧拉表示不同!例如,围绕(0.7, 0.0, 0.7) 旋转90° 所产生的旋转与(63°, 0°, 63°) 的欧拉旋转完全不同!

    相反,只需始终使用rollAxis 作为角度/轴表示。您可以使用Quaternion.AngleAxis 获取四元数形式。


    第二个问题是全局与局部旋转。

    这是一个您肯定已经注意到其影响的问题。

    在第一部分中,您将rollAxis 应用为局部旋转。这是因为rollAxis* 运算符的第二项。

    在第二部分中,RotateAround 围绕由rollAxis 定义的全局轴旋转。

    两者都保持全局或本地。全局更简单,它似乎就是你想要做的(从transform.position + direction 判断),所以你应该将rotation 作为* 运算符的第二项。 p>


    总而言之,只需更改Quaternion endRotation = rotation * Quaternion.Euler(rollAxis * rollAngle); 行即可解决问题:

    Vector3 rollAxis = Vector3.Cross(Vector3.up, direction);
    
    Quaternion rotation = transform.rotation;
    Quaternion endRotation = Quaternion.AngleAxis(rollAngle, rollAxis) * rotation;
    
    // ...
    
        transform.RotateAround(pointAround, rollAxis, rotateThrough);
    

    See here 了解有关四元数 * 运算符的更多信息。

    【讨论】:

    • 谢谢,只是我没那么有经验。不过非常感谢。
    • ...感谢您发布有关 * 运算符的参考链接
    【解决方案2】:

    我建议你使用 DoTween 资产 (https://assetstore.unity.com/packages/tools/animation/dotween-hotween-v2-27676):

    DORotate(Vector3 to, float duration);

    使用补间动画将为您节省大量编写自己动画的时间。

    【讨论】:

    • Asker 询问如何获取将用作to 参数的四元数。所以不幸的是,这个答案并没有真正的帮助。
    猜你喜欢
    • 1970-01-01
    • 2022-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多