Unity Input System Drag 拖动后有一个偏移量
Unity Input System Drag having an offset after dragging
我是新Unity输入系统的新手,实现了拖动算法。它应该在点击和拖动时与鼠标一起工作。拖动操作将移动 cimemachine cameraTarget,因此相机会随之移动。它正在工作,但错误是:拖动后它有一点偏移。所以在屏幕上的拖动不是 1:1 拖动 cameraTarget。知道为什么会这样吗?
这是我的代码:
public class DragManager : MonoBehaviour
{
private InputControls.MouseActions mouseActions;
private Coroutine _coroutine;
private CameraHandler cameraHandler;
private Vector3 _pointerStartPosition;
private Vector3 _pointerCurrentPosition;
private void OnEnable()
{
cameraHandler = CameraHandler.Instance;
mouseActions.Enable();
mouseActions.Drag.started += Drag_started;
mouseActions.Drag.canceled += Drag_canceled;
}
private void OnDisable()
{
mouseActions.Drag.started -= Drag_started;
mouseActions.Drag.canceled -= Drag_canceled;
mouseActions.Disable();
}
private void Awake()
{
mouseActions = new InputControls().Mouse;
}
private void Drag_started(InputAction.CallbackContext obj)
{
_pointerStartPosition = mouseActions.MousePosition.ReadValue<Vector2>();
_coroutine = StartCoroutine(HandleDragCoroutine());
}
private void Drag_canceled(InputAction.CallbackContext obj)
{
StopCoroutine(_coroutine);
}
private IEnumerator HandleDragCoroutine()
{
while (true)
{
_pointerCurrentPosition = mouseActions.MousePosition.ReadValue<Vector2>();
var dragIteration = _pointerStartPosition - _pointerCurrentPosition; // drag _pointerCurrentPosition to _pointerStartPosition
var cameraTargetTransform = cameraHandler.GetCameraTargetTransform();
cameraTargetTransform.position += delta * Time.deltaTime;
_pointerStartPosition = _pointerCurrentPosition;
yield return null; // wait for new frame Update
}
}
}
在unity中很常见,我经历了这么多时间
试试这个:
public static Vector2 TouchToScreenPoint(RectTransform draggingCanvasRectTransform)
{
Vector2 position = Vector2.zero ;
if (Input.touchCount > 0)
{
// respect only first touch, mousePosition module will update on each finger touch the screen.
RectTransformUtility.ScreenPointToLocalPointInRectangle(draggingCanvasRectTransform, Input.touches[0].position,
Camera.main, out position);
}
}
这在任何屏幕尺寸上都适用,您可以参考您使用的任何相机和您使用的主要 canvas。
希望这对你有用
所以几个小时后我找到了解决方案。以下是更新后的代码。
说明:
- 我不得不重新计算鼠标在世界中的位置space(虽然看起来是正确的)
- 删除与 Time.deltaTime 的乘法,因为这会导致最小的移动。
- 除此之外,我还在使用 Cinemachine。在虚拟凸轮上,我必须将软区 Height/Width 设置为零 (0)。否则拖动时相机会弹起。
public class DragManager : MonoBehaviour
{
private InputControls.MouseActions mouseActions;
private InputControls.TouchActions touchActions;
private Coroutine _coroutine;
private CameraTarget cameraTarget;
private Camera _camera;
private Vector3 _pointerStartPosition;
private Vector3 _pointerCurrentPosition;
private void OnEnable()
{
cameraTarget = CameraTarget.Instance;
mouseActions.Enable();
mouseActions.Drag.started += Mouse_Drag_started;
mouseActions.Drag.canceled += Drag_canceled;
}
private void OnDisable()
{
mouseActions.Drag.started -= Mouse_Drag_started;
mouseActions.Drag.canceled -= Drag_canceled;
mouseActions.Disable();
}
private void Awake()
{
mouseActions = new InputControls().Mouse;
_camera = Camera.main;
}
private void Mouse_Drag_started(InputAction.CallbackContext obj)
{
_pointerStartPosition = CalculatePositionToWorldSpace(mouseActions.MousePosition.ReadValue<Vector2>());
_coroutine = StartCoroutine(HandleDragCoroutine(mouseActions.MousePosition));
}
private Vector3 CalculatePositionToWorldSpace(Vector3 _pointerPosition)
{
var worldDirection = _camera.ScreenToWorldPoint(_pointerPosition);
worldDirection.z = 0f;
return worldDirection - cameraTarget.Transform.position;
}
private void Drag_canceled(InputAction.CallbackContext obj)
{
if (_coroutine != null)
StopCoroutine(_coroutine);
}
private IEnumerator HandleDragCoroutine(InputAction pointerPositionInputAction)
{
while (true)
{
_pointerCurrentPosition = CalculatePositionToWorldSpace(pointerPositionInputAction.ReadValue<Vector2>());
var dragIteration = _pointerStartPosition - _pointerCurrentPosition; // drag _pointerCurrentPosition to _pointerStartPosition
cameraTarget.Transform.position += dragIteration;
_pointerStartPosition = _pointerCurrentPosition;
yield return null; // wait for new frame Update
}
}
}
我是新Unity输入系统的新手,实现了拖动算法。它应该在点击和拖动时与鼠标一起工作。拖动操作将移动 cimemachine cameraTarget,因此相机会随之移动。它正在工作,但错误是:拖动后它有一点偏移。所以在屏幕上的拖动不是 1:1 拖动 cameraTarget。知道为什么会这样吗?
这是我的代码:
public class DragManager : MonoBehaviour
{
private InputControls.MouseActions mouseActions;
private Coroutine _coroutine;
private CameraHandler cameraHandler;
private Vector3 _pointerStartPosition;
private Vector3 _pointerCurrentPosition;
private void OnEnable()
{
cameraHandler = CameraHandler.Instance;
mouseActions.Enable();
mouseActions.Drag.started += Drag_started;
mouseActions.Drag.canceled += Drag_canceled;
}
private void OnDisable()
{
mouseActions.Drag.started -= Drag_started;
mouseActions.Drag.canceled -= Drag_canceled;
mouseActions.Disable();
}
private void Awake()
{
mouseActions = new InputControls().Mouse;
}
private void Drag_started(InputAction.CallbackContext obj)
{
_pointerStartPosition = mouseActions.MousePosition.ReadValue<Vector2>();
_coroutine = StartCoroutine(HandleDragCoroutine());
}
private void Drag_canceled(InputAction.CallbackContext obj)
{
StopCoroutine(_coroutine);
}
private IEnumerator HandleDragCoroutine()
{
while (true)
{
_pointerCurrentPosition = mouseActions.MousePosition.ReadValue<Vector2>();
var dragIteration = _pointerStartPosition - _pointerCurrentPosition; // drag _pointerCurrentPosition to _pointerStartPosition
var cameraTargetTransform = cameraHandler.GetCameraTargetTransform();
cameraTargetTransform.position += delta * Time.deltaTime;
_pointerStartPosition = _pointerCurrentPosition;
yield return null; // wait for new frame Update
}
}
}
在unity中很常见,我经历了这么多时间
试试这个:
public static Vector2 TouchToScreenPoint(RectTransform draggingCanvasRectTransform)
{
Vector2 position = Vector2.zero ;
if (Input.touchCount > 0)
{
// respect only first touch, mousePosition module will update on each finger touch the screen.
RectTransformUtility.ScreenPointToLocalPointInRectangle(draggingCanvasRectTransform, Input.touches[0].position,
Camera.main, out position);
}
}
这在任何屏幕尺寸上都适用,您可以参考您使用的任何相机和您使用的主要 canvas。
希望这对你有用
所以几个小时后我找到了解决方案。以下是更新后的代码。
说明:
- 我不得不重新计算鼠标在世界中的位置space(虽然看起来是正确的)
- 删除与 Time.deltaTime 的乘法,因为这会导致最小的移动。
- 除此之外,我还在使用 Cinemachine。在虚拟凸轮上,我必须将软区 Height/Width 设置为零 (0)。否则拖动时相机会弹起。
public class DragManager : MonoBehaviour
{
private InputControls.MouseActions mouseActions;
private InputControls.TouchActions touchActions;
private Coroutine _coroutine;
private CameraTarget cameraTarget;
private Camera _camera;
private Vector3 _pointerStartPosition;
private Vector3 _pointerCurrentPosition;
private void OnEnable()
{
cameraTarget = CameraTarget.Instance;
mouseActions.Enable();
mouseActions.Drag.started += Mouse_Drag_started;
mouseActions.Drag.canceled += Drag_canceled;
}
private void OnDisable()
{
mouseActions.Drag.started -= Mouse_Drag_started;
mouseActions.Drag.canceled -= Drag_canceled;
mouseActions.Disable();
}
private void Awake()
{
mouseActions = new InputControls().Mouse;
_camera = Camera.main;
}
private void Mouse_Drag_started(InputAction.CallbackContext obj)
{
_pointerStartPosition = CalculatePositionToWorldSpace(mouseActions.MousePosition.ReadValue<Vector2>());
_coroutine = StartCoroutine(HandleDragCoroutine(mouseActions.MousePosition));
}
private Vector3 CalculatePositionToWorldSpace(Vector3 _pointerPosition)
{
var worldDirection = _camera.ScreenToWorldPoint(_pointerPosition);
worldDirection.z = 0f;
return worldDirection - cameraTarget.Transform.position;
}
private void Drag_canceled(InputAction.CallbackContext obj)
{
if (_coroutine != null)
StopCoroutine(_coroutine);
}
private IEnumerator HandleDragCoroutine(InputAction pointerPositionInputAction)
{
while (true)
{
_pointerCurrentPosition = CalculatePositionToWorldSpace(pointerPositionInputAction.ReadValue<Vector2>());
var dragIteration = _pointerStartPosition - _pointerCurrentPosition; // drag _pointerCurrentPosition to _pointerStartPosition
cameraTarget.Transform.position += dragIteration;
_pointerStartPosition = _pointerCurrentPosition;
yield return null; // wait for new frame Update
}
}
}