Unity 3D四元数旋转:请帮助我避免云台锁定并平滑旋转

问题描述 投票:0回答:1

嗯,事情就是这样。我目前正在开发一款手机游戏,这是一个相当简单的核心机制,您从一个3D立方体开始,每回合都会得到一个新的立方体,需要将其放置或捕捉到场景中的立方体表面。多维数据集的每个面都有一个值,并由“城市区域类型”表示。说出房屋面积,公园,垃圾场等。出于我的问题,我不会输入游戏设计细节。但是,您的目标是创建具有最大价值的CubeCity。正如我之前说过的,每次创建和放置一个多维数据集时,都会使用随机值(面部类型)为您提供一个新的多维数据集,该新多维数据集将在“ previewCube”上表示,用于预览所需的最终结果。您正在创建的城市。您可以选择场景中多维数据集的不同面,预览多维数据集将在该面附近生成,因此您可以旋转它并找到所需的位置。当您对选择感到满意时,只需点击“构建多维数据集按钮”,预览多维数据集将消失,并且具有相同值和旋转度的新多维数据集将出现在所选面上。那是我遇到麻烦的时候。我遇到了很多麻烦,只是在3D空间上旋转预览多维数据集,在犯了很多错误之后,我遇到了一个很差的解决方案,但是它不应该工作。在其代码下,我认为一种更可靠的方法是将旋转限制或限制在2个角度以内,但尝试后仍无法找到方法。我几乎到处搜索,但没有简单的直接方法可以解决此问题。该脚本旋转对象以避免万向节锁定错误,但这并不精确,因为每次进行新旋转时,由于deltaTime都会产生更多偏移。我只需要围绕选定的轴90或-90度旋转对象。那个,但是没用,呵呵,如果有人可以帮助我,那会很多,这困扰着我好几天了。谢谢!

public class CubeBehaviour : MonoBehaviour

{私人运动_运动;

private void Awake()
{
    if (!GetComponent<Movement>())
        Debug.LogWarning("Please add a movement script to the gameobject.");

    _movement = GetComponent<Movement>();
}

public void Move(Vector3[] positions, Action callBack)
{
    _movement.StartMove(positions,callBack);
}

[ContextMenu("Rotate X Positive")]
public void RotateAround_xAxisPositive()
{
    Rotate(RotationAxis.X, true);
}

[ContextMenu("Rotate X Negative")]
public void RotateAround_xAxisNegative()
{
    Rotate(RotationAxis.X, false);
}

[ContextMenu("Rotate Y Positive")]
public void RotateAround_yAxisPositive()
{
    Rotate(RotationAxis.Y, true);
}

[ContextMenu("Rotate Y Negative")]
public void RotateAround_yAxisNegative()
{
    Rotate(RotationAxis.Y, false);
}

[ContextMenu("Rotate Z Positive")]
public void RotateAround_zAxisPositive()
{
    Rotate(RotationAxis.Z, true);
}

[ContextMenu("Rotate Z Negative")]
public void RotateAround_zAxisNegative()
{
    Rotate(RotationAxis.Z, false);
}

public void Rotate(RotationAxis axis, bool positiveRotation)
{
    StartCoroutine(DoRotation(axis,90, positiveRotation));
}

IEnumerator DoRotation(RotationAxis axis,float angles, bool positiveRotation)
{
    float time = 1;
    float elapsedTime = 0;
    Quaternion destinationRotation = Quaternion.identity;
    Vector3 anglesToRotate = Vector3.zero;

    switch (axis)
    {
        case RotationAxis.X:
            if (positiveRotation)
                anglesToRotate = new Vector3(90, 0, 0);
            else
                anglesToRotate = new Vector3(-90, 0, 0);
            break;
        case RotationAxis.Y:
            if (positiveRotation)
                anglesToRotate = new Vector3(0, 90, 0);
            else
                anglesToRotate = new Vector3(0, -90, 0);
            break;
        case RotationAxis.Z:
            if (positiveRotation)
                anglesToRotate = new Vector3(0, 0, 90);
            else
                anglesToRotate = new Vector3(0, 0, -90);
            break;
        default:
            Debug.LogError("You must assign a rotation axis!");
            break;
    }
    destinationRotation *= this.transform.rotation * Quaternion.Euler(anglesToRotate);

    Quaternion yRotation = Quaternion.identity;
    Quaternion xRotation = Quaternion.identity;
    Quaternion zRotation = Quaternion.identity;


    while (elapsedTime < time)
    {
        yRotation = Quaternion.AngleAxis(anglesToRotate.y * Time.deltaTime, Vector3.up);
        xRotation = Quaternion.AngleAxis(anglesToRotate.x * Time.deltaTime, Vector3.right);
        zRotation = Quaternion.AngleAxis(anglesToRotate.z * Time.deltaTime, Vector3.forward);

        this.transform.rotation = yRotation * xRotation * zRotation * this.transform.rotation;

        elapsedTime += Time.deltaTime;
        yield return null;
    }
    //this.transform.rotation = yRotation * xRotation * zRotation;
    //this.transform.rotation = destinationRotation;
}

}

公共枚举RotationAxis{X,是的ž}

unity3d rotation quaternions
1个回答
0
投票
您永远都不应该像这样设置旋转角度,它将根本无法正常工作,并且Unity文档也对此进行了警告。

this.transform.rotation = yRotation * xRotation * zRotation * this.transform.rotation;

如果一次旋转一个轴,则可以使用。

transform.Rotate(90.0f ,0.0f,0.0f,Space.World);

https://docs.unity3d.com/ScriptReference/Transform.Rotate.html

您也可以使用LookAt

transform.LookAt(targetCube);

https://docs.unity3d.com/ScriptReference/Transform.LookAt.html

您也可以使用Quaternion.Lerp

https://docs.unity3d.com/ScriptReference/Quaternion.Lerp.html

通常,Unity中的旋转可能很棘手,尤其是在检查器中看起来很容易的情况下。

© www.soinside.com 2019 - 2024. All rights reserved.