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

时间:2018-10-27 23:08:59

标签: c# unity3d augmented-reality vuforia

我正在开发一个简单的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);
} 

这不是我所需要的,无论我从哪个角度看,如何都可以根据手指滑动方向旋转对象?

UPD:
一个简单的非AR示例,可以帮助您了解我所需要的ios游戏“ Space Frontier 2” 。成功发射火箭后,它会落在行星上,您可以用手指轻扫来旋转行星。

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

3 个答案:

答案 0 :(得分:2)

无论您物体旋转的方向如何,也无论相机相对于该物体的位置如何,此效果都很好:

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”标签,或者在必要时在外部分配相机。

答案 1 :(得分:1)

我现在没有确切的密码。

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

考虑一个垂直分离的,具有蓝色和红色2种颜色的真实球。 当您在其前面时,仅看到蓝色的一面,将其向​​上抚摸将使蓝色的面朝上,而红色的面从底部出现。 现在,向后移动,仅看到红色的一面,然后再次向上滑动。 蓝色的面孔将下降并从底部出现。 Unity将物理应用于虚拟对象的方式与我们与真实对象进行交互的方式相同。

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

我希望这很清楚,可以让您进行修复。

答案 2 :(得分:1)

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

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;
}

看看是否可行,当然,尝试使用这些值。