两指合一的相机轨道旋转

Posted

技术标签:

【中文标题】两指合一的相机轨道旋转【英文标题】:Orbital rotation of the camera with two fingers in a unity 【发布时间】:2022-01-08 09:20:17 【问题描述】:

几天来我一直无法弄清楚。您需要使用手机上的两根手指使相机围绕某个对象旋转。我用手指转了一圈,它应该会旋转。 我找到了一个解决方案,但由于某种原因,相机在旋转过程中经常抽搐,有时会非常强烈地转动,并且有一点移动。我怎样才能做得更好?

public void Execute()
    
        if (_officeModel.Camera.orthographic) return;

        _camera = _officeModel.Camera.transform;

        var pos1 = CreateRaycast(Input.GetTouch(0).position);
        var pos2 = CreateRaycast(Input.GetTouch(1).position);
        var pos1b = CreateRaycast(Input.GetTouch(0).position - Input.GetTouch(0).deltaPosition);
        var pos2b = CreateRaycast(Input.GetTouch(1).position - Input.GetTouch(1).deltaPosition);

        var screenCenter = _officeModel.SelectedObject == null ? CreateRaycast(new Vector3(Screen.width / 2, Screen.height / 2, 0)) : _officeModel.SelectedObject.transform.position; //Get screen center transform
        _camera.RotateAround(screenCenter, Vector3.up, Vector3.SignedAngle(pos2 - pos1, pos2b - pos1b, Vector3.up));
        _officeModel.CameraPos = _camera.position;
    
    
    private Vector3 CreateRaycast(Vector3 direction)
    
        RaycastHit hit;
        Vector3 point = Vector3.zero;
        Ray ray = _officeModel.Camera.ScreenPointToRay(direction);
        if (Physics.Raycast(ray, out hit))
            point = hit.point;
        return point;
    

【问题讨论】:

【参考方案1】:

首先,您应该确保检查有 2 个位置没有开始或结束。

另外,我不会使用光线投射来计算你的旋转角度,因为如果触摸的光线突然错过模型以及其他奇怪的情况,那会很尴尬。

请务必注意RotateAround 的更改。

public void Execute()

    if (_officeModel.Camera.orthographic) return;

    _camera = _officeModel.Camera.transform;

    if (Input.touchCount < 2) 
    
        return;
    
    
    Touch touch0 = Input.GetTouch(0);
    switch (touch0.touchPhase) 
        case TouchPhase.Stationary:
            break;
        case TouchPhase.Moved:
            break;
        default: 
            return;
    

    Touch touch1 = Input.GetTouch(1);
    switch (touch1.touchPhase) 
        case TouchPhase.Stationary:
            break;
        case TouchPhase.Moved:
            break;
        default:
            return;
    

    var pos1 = touch0.position;
    var pos2 = touch1.position;
    var pos1b = touch0.position - touch0.deltaPosition;
    var pos2b = touch1.position - touch1.deltaPosition;

    // Get screen center transform
    var screenCenter = _officeModel.SelectedObject == null ? CreateRaycast(
            new Vector3(Screen.width / 2, Screen.height / 2, 0)) 
            : _officeModel.SelectedObject.transform.position; 

    _camera.RotateAround(screenCenter, Vector3.up, 
             Vector3.SignedAngle(pos2b - pos1b, pos2 - pos1, Vector3.forward));

    _officeModel.CameraPos = _camera.position;


private Vector3 CreateRaycast(Vector3 direction)

    RaycastHit hit;
    Vector3 point = Vector3.zero;
    Ray ray = _officeModel.Camera.ScreenPointToRay(direction);
    if (Physics.Raycast(ray, out hit))
        point = hit.point;
    return point;

【讨论】:

非常感谢您的帮助,直到现在我才设法回答。一切正常! @DavidBaranovsky 很高兴我能提供帮助,如果您觉得有帮助,请不要忘记 accept the answer。它给了我一些声誉积分,并帮助搜索面板上有类似问题的人看到这里有一个有用的答案。

以上是关于两指合一的相机轨道旋转的主要内容,如果未能解决你的问题,请参考以下文章

three.js 围绕 Y 轴的相机旋转似乎关闭

Threejs在使用变换控制时禁用轨道相机

使用vue学习three.js之移动相机-使用轨道控件OrbitControls控制相机

在 SceneKit 中禁用相机平移

SceneKit:围绕任意点进行轨道运行而无需相机跳跃或将锚点移动到中心?

没有元素旋转的轨道动画