I am new to the new Unity Input System and implemented a dragging algorithm. It should work with the mouse upon click&drag. The dragging operation will move the cimemachine cameraTarget, and therefore the camera follows. It is working, but the fault is: after dragging it has a little offset. So the dragging on the screen is not 1:1 dragging the cameraTarget. Any ideas why this is happening?
here is my code:
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
}
}
}
CodePudding user response:
Its common in unity, I went through this tons of time
Try this:
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);
}
}
This works all the way on any screen size , you can reference whatever camera you are using and the main canvas you are using.
Hope this works out for you
CodePudding user response:
So after couple of hours I found the solution. Below is the updated Code.
Explanation:
- I had to recalculate the mouse position to world space (although it seemed correct)
- remove the multiplication with Time.deltaTime, as this would lead to minimal movement.
- Additionally to that, I was using Cinemachine. And on the virtual cam I had to set Soft Zone Height/Width to zero (0). Otherwise the camera would bounce when dragging.
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
}
}
}
