Problem dragging object with mouse and touch unity

Hello guys, what I want to achieve is to drag an object around the screen with mouse and with touch, having the y position of that object always in 0.2f and moving the object just by integer position values(i want this because i’m working inside a grid with tile positioned in integer values, and i want that my object can be positioned inside this grid, in the middle of the tiles).

I can make this object move and this is the code (for the mouse):

private Vector3 screenPoint;
    private Vector3 offset;

    void OnMouseDown()
    {
        Debug.Log("down");
        screenPoint = Camera.main.WorldToScreenPoint(gameObject.transform.position);
        offset = gameObject.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));
        offset = new Vector3(offset.x, offset.y, offset.z);
    }

    void OnMouseDrag()
    {
        Debug.Log("drag");
        Vector3 cursorPoint = new Vector3((int)Input.mousePosition.x, (int)Input.mousePosition.y, (int)screenPoint.z);
        Vector3 cursorPosition = Camera.main.ScreenToWorldPoint(cursorPoint) + offset;
        transform.position = new Vector3((int)cursorPosition.x, 0.2f, (int)cursorPosition.z);
    }
  1. the problem with this is that it doesn’t follow correctly my mouse (for example, if i move my mouse from 1 to 10, this object moves from 1 to 3). How can i solve it?

  2. how can I achieve the same thing with touch functions?

Thank you in advance.

Would it be accurate to say that your tiles are all at the same height and you only want to move the object if you go to the next tile? If this is correct, I wonder if maybe using the IDragHandler interface, in conjunction with IPointerEnter would enable you to move them in a snap-to-grid like fashion. Check below for a little more info on the IPointer interfaces, which could be useful to you whether this design is what you had meant or not.

A separate note, but relevant to your question in general:
I would recommend using the IPointer interfaces, which work for both mouse and touch. They include Up, Down, Click, Drag, and Drop (and others).

Hi again methos. First of all thank you for your reply. After your suggestion i changed my functions like this:

private Vector3 screenPoint;
    private Vector3 offset;

    public void OnPointerDown(PointerEventData eventData)
    {
        if (!LevelEditor.disableTouch)
        {
            screenPoint = Camera.main.WorldToScreenPoint(gameObject.transform.position);
            offset = gameObject.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));
        }
    }

    public void OnDrag(PointerEventData eventData)
    {
        if (!LevelEditor.disableTouch)
        {
            Vector3 cursorPoint = new Vector3((int)Input.mousePosition.x, (int)Input.mousePosition.y, (int)screenPoint.z);
            Vector3 cursorPosition = Camera.main.ScreenToWorldPoint(cursorPoint) + offset;
            transform.position = new Vector3((int)cursorPosition.x, 0.2f, (int)cursorPosition.z);
        }
    }

It’s the same as before but now it works for both touch and mouse like you suggested.

Unfortunately, the question is still open. “Would it be accurate to say that your tiles are all at the same height and you only want to move the object if you go to the next tile?” the answer is yes. With this code it goes from tile to tile, but it doesn’t follow correctly the touch/mouse. The offset between the mouse and the object is too high, for example if i move the mouse from x=0 to x=10 (i’m inventing these numbers, just to do an example), the object is moving from x=0 to x=3, but I don’t have an Idea on how to fix this. Have you got some suggestions?

Okay, well I can try to help. I’m a little foggy on trying to comprehend your design, how the grid is working.
When you say you move from 0 → 10, in your example, but the object is moving from 0-> 3 – was the object supposed to go to 10? :slight_smile:
Is it the offset that’s messing it up?

If you have a simple project (unity package ) that you could toss in the thread, I could look at it.

1 Like

Yes, it is supposed to go from 0->10 too, changing the x and the z axis of the object but not the y one (in my code I want that, when I move the object, it must remain in y = 0.2f)!

Imagine that the object is in the lower left corner of the screen, from there you can move it along all the map, but just in integer axis position (if in the beginning it is for example in x= 10.5 z=-9.5, when I move the object, it must go, for example, to x=9 and z=-7, and never go in a “float” position again). My code does this, but it doesn’t follow very well my mouse/touch. If for example the object is in x=0 z=0, I’m moving the object and my mouse is in x=5 z=3, probably the object is still in x=2 z=1 (again, I’m showing you random numbers, just to let you understand the problem).

Unfortunately I don’t have a small unitypack to send you, but I can make you a gif when I’m back home! Thank you anyway

Well, I can understand what’s happening without the gif. I just thought the package might help me play around a bit to see if I could come up with an answer for you.

Did you ever try my suggestion about using OnPointerEnter for your grid? Are they game objects that you could implement that interface on?

Hmm, interestingly enough, I pasted your code into a project and it’s working very well/accurately. My cube follows the mouse almost exactly (but stays at 1 unit spacing), and goes just as far as my mouse.

Sorry, 1 correction: My cube (dragged object) has its ‘z’ position (in my current view) that gets messed up. It goes “-1” on every click down to begin drag. At zero (initially started at ‘5’) it stops. I’m not sure maybe that is somehow related.

I could remedy that small z-axis issue like this:

private Vector3 screenPoint;
   // private Vector3 offset;

    public void OnPointerDown(PointerEventData eventData)
    {  
        screenPoint = Camera.main.WorldToScreenPoint(gameObject.transform.position);
       // offset = gameObject.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Mathf.Abs(transform.position.z - Camera.main.transform.position.z)));
    }

    public void OnDrag(PointerEventData eventData)
    {
        Vector3 cursorPoint = new Vector3((int)Input.mousePosition.x, (int)Input.mousePosition.y, Mathf.Abs(transform.position.z - Camera.main.transform.position.z));
        Vector3 cursorPosition = Camera.main.ScreenToWorldPoint(cursorPoint);
        transform.position = new Vector3((int)cursorPosition.x, 0.2f, (int)cursorPosition.z);
    }

Still not sure if that would solve your issue, as it was different from what I saw. Hope you get it sorted out. :slight_smile:

Where should I put the OnPointerEnter and what should I write on it?

That’s so strange that works for you lol, maybe later I will give you some screens about my gameobjects or something like that so we can come up with something

I didn’t even need the OnPointerEnter after all…

Here you can find a series of screens inside the game. Something strange is happening here cause your modifications to the code are totally buggy to me! Let me know what do you think

Ah okay, so my design was all flat. lol. I only ever moved along the x-axis in my test.

Any ideas? Lol

Sorry not right now, can’t think of anything.

Hello, I have this exactly problem too. Have you found the solution?

I have a GameObject Parent with a child GameObj that have a World Space Canvas.

Thank you.