用两个手指统一旋转相机的轨道
Orbital rotation of the camera with two fingers in a unity
几天来我一直没弄明白。您需要在 phone 上用两根手指使相机围绕某个物体旋转。我用手指转了一圈,它应该会旋转。
我找到了一个解决方案,但由于某种原因,相机在旋转过程中经常会抽动,有时会非常强烈地转动,并有一点移动。我怎样才能做得更好?
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;
}
首先,您应该确保检查有 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;
}
几天来我一直没弄明白。您需要在 phone 上用两根手指使相机围绕某个物体旋转。我用手指转了一圈,它应该会旋转。 我找到了一个解决方案,但由于某种原因,相机在旋转过程中经常会抽动,有时会非常强烈地转动,并有一点移动。我怎样才能做得更好?
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;
}
首先,您应该确保检查有 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;
}