如何用手指滑动沿所有 3 个轴旋转对象?

How to rotate an object along all 3 axes with finger swipe?

我正在开发一个简单的 AR Vuforia 应用程序。如何通过一根手指滑动实现对象沿所有三个轴的旋转?

我目前使用的代码有一个错误:物体的旋转取决于它的局部轴。例如,如果我从正面看物体,一切正常,但如果我从背面看物体,手指向上滑动会使它向下旋转,反之亦然。

这是这个脚本:

public float rotSpeed = 30f;

void OnMouseDrag()
{
float rotX = Input.GetAxis("Mouse X")*rotSpeed*Mathf.Deg2Rad;
float rotY = Input.GetAxis("Mouse Y")*rotSpeed*Mathf.Deg2Rad;

transform.Rotate(Vector3.up, -rotX);
transform.Rotate(Vector3.right, -rotY);
} 

这不是我需要的,如何根据手指滑动方向旋转对象,而不管我从哪个角度看?

更新

一个简单的非 AR 示例,可以帮助您理解我需要的是 iOS 游戏 "Space Frontier 2"。火箭成功发射后,它会降落在星球上,你可以用手指滑动来旋转星球。

这是视频演示:https://youtu.be/OiNPP1WNIAI

我现在没有确切的密码。

但是如果你没有更新你的视点坐标,这应该是预期的结果。

考虑一个真正的球,它有两种颜色,蓝色和红色,垂直分开。 当你在它面前时,只看到蓝色的一面,向上抚摸它会使蓝色的一面上升,红色的一面从底部出现。 现在移到它后面,只看到红色的一面,然后再次向上抚摸它。 蓝色的脸会下降并从底部出现。 Unity 将物理学应用于虚拟对象,就像我们与真实对象交互一样。

因此,在向其应用移动时,您需要考虑相机位置和对象方向。 您需要根据与对象原点方向相关的相机位置将变换矩阵应用于您的运动。

我希望这足够清楚,可以让您走上正轨来修复它。

我认为您必须以某种方式限制旋转以获得所需的行为。我最近写了一个脚本来做到这一点。不过我做了一点修改。

public float rotSpeed = 30f;

float ClampAngle(float _angle, float _min, float _max)
{
    if (_angle < 0f) _angle = 360 + _angle;
    if (_angle > 180f) Mathf.Max(_angle, 360 + _min);
    return Mathf.Min(_angle, _max);
}

用法:

void RotateGameObject()
{
    float h = Input.GetTouch(0).deltaPosition.x * Time.deltaTime * rotSpeed*Mathf.Deg2Rad;
    float v = Input.GetTouch(0).deltaPosition.y * Time.deltaTime * rotSpeed*Mathf.Deg2Rad;

    Vector3 rot = transform.rotation.eulerAngles + new Vector3(-v, h, 0f);
    //Change the y & z values to match your expected behaviour.
    rot.x = ClampAngle(rot.x, -5f, 20f);
    //Clamp rotation on the y-axis
    rot.y = ClampAngle(rot.y, -20f, 20f);
    transform.eulerAngles = rot;
}

看看这是否有效,当然,尝试使用这些值。

无论您的物体旋转如何,也无论您的相机相对于物体的位置如何,这都很有效:

public float rotSpeed = 30f;

void OnMouseDrag()
{
    float rotX = Input.GetAxis("Mouse X") * rotSpeed;
    float rotY = Input.GetAxis("Mouse Y") * rotSpeed;

    Camera camera = Camera.main;

    Vector3 right = Vector3.Cross(camera.transform.up, transform.position - camera.transform.position);
    Vector3 up = Vector3.Cross(transform.position - camera.transform.position, right);

    transform.rotation = Quaternion.AngleAxis(-rotX, up) * transform.rotation;
    transform.rotation = Quaternion.AngleAxis(rotY, right) * transform.rotation;
}

确保您的相机具有 "MainCamera" 标签,或在必要时从外部分配相机。