Reputation: 883
I'm currently working on a basic card game in Unity and I'm having a fair bit of trouble working out how to perform a drag on my cards. My current layout is as follows:
I'm currently trying to use the IDragHandler
interface to receive callbacks whenever a drag event is detected over my card object.
My end goal is to be able to slide the cards to the left/right based on the x axis of a touch/mouse slide.
I've currently tried using the eventdata.delta value passed into OnDrag() IDragHandler to move my card but this value, from what I can tell, is in pixels and when converted to world units using Camera.main.ScreenToWorldPoint() results in a value of 0,0,0. Likewise trying to keep track of where the drag started and subtracting the current position result in a value of 0,0,0.
I'm currently at a bit of a loss as to how I can drag a game object using world units so I'd greatly appreciate it if someone can provide me some guidance.
Thanks
EDIT:
^This is why you shouldn't StackOverflow late at night.
So to add some extra context:
public void OnDrag(PointerEventData eventData)
{
Vector2 current = Camera.main.ScreenToWorldPoint(eventData.position);
Debug.Log("Current world position: "+current);
Vector3 delta = lastDragPoint - current;
// Store current value for next call to OnDrag
lastDragPoint = eventData.position;
// Now use the values in delta to move the cards
}
Using this approach I always get a value of 0,0,0 after my call to ScreenToWorldPoint
so I cant move the cards
The second approach I've tried is:
public void OnDrag(PointerEventData eventData)
{
Vector3 screenCenter = new Vector3(Screen.width * 0.5f, Screen.height * 0.5f, 1f);
Vector3 screenTouch = screenCenter + new Vector3(eventData.delta.x, eventData.delta.y, 0f);
Vector3 worldCenterPosition = Camera.main.ScreenToWorldPoint(screenCenter);
Vector3 worldTouchPosition = Camera.main.ScreenToWorldPoint(screenTouch);
Vector3 delta = worldTouchPosition - worldCenterPosition;
// Now use the values in delta to move the cards
}
Using this approach I get a much better result (the cards actually move) but they don't correctly follow the mouse. If I drag a card I will move in the direction of the mouse however the distance moved is significantly less than the distance the mouse moved (i.e. by the time the mouse has reached the edge of the screen the card has only moved one cards width)
Upvotes: 2
Views: 5213
Reputation: 883
So after a bit of playing around and inspecting the various values I was receiving from the calls to ScreenToWorldPoint I finally tracked down the issue. In the code for my second attempted approach I found that I was using an incorrect value for the Z argument in ScreenToWorldPoint. After doing a bit of research I found that his should be the Z distance between the camera and the (i guess) touch surface.
Vector3 screenCenter = new Vector3(Screen.width * 0.5f, Screen.height * 0.5f, -Camera.main.transform.position.z);
Vector3 screenTouch = screenCenter + new Vector3(eventData.delta.x, eventData.delta.y, 0);
Thanks to everyone who took the time to read through my question.
Upvotes: 2
Reputation: 34
You could use OnMouseDown -method to detect when player starts to drag the card and update its positions according to mouse position. When the drag ends the OnMouseUp -method is called.
https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnMouseDown.html https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnMouseUp.html
Upvotes: -1