Christian Webb
Christian Webb

Reputation: 427

How to do Drag and Drop on X & Z Axis in Unity3D?

I have been trying to make Drag and Drop of Objects in Unity 3D work on mobile. I would like it to be so that as you drag across the screen the object moves on z axis, and if you drag up or down the screen the object will move in the z axis rather than the y. This is the code I currently have...

public class MovementController : MonoBehaviour
{
Vector3 dist;
Vector3 startPos;
float posX;
float posZ;
float posY;
void OnMouseDown()
{
    startPos = transform.position;
    dist = Camera.main.WorldToScreenPoint(transform.position);
    posX = Input.mousePosition.x - dist.x;
    posY = Input.mousePosition.y - dist.y;
    posZ = Input.mousePosition.z - dist.z;
}

void OnMouseDrag()
{
    float disX = Input.mousePosition.x - posX;
    float disY = Input.mousePosition.y - posY;
    float disZ = Input.mousePosition.z - posZ;
    Vector3 lastPos = Camera.main.ScreenToWorldPoint(new Vector3(disX, disY, disZ));
    transform.position = new Vector3(lastPos.x, startPos.y, lastPos.z);

}
}

However this makes the object only move a tiny amount on the z axis, I have to go right to the top of the screen for it to move just a bit. Is there a better way to do this as I cant seem to find a way to change the code to fix this issue. Thanks.

Upvotes: 0

Views: 2916

Answers (1)

Jinjinov
Jinjinov

Reputation: 2683

you confused the purpose of your variables a little - they did not contain the values that their names described :)

use this for XY plane:

public class MovementController : MonoBehaviour
{
    Vector3 startPos;
    Vector3 dist;

    void OnMouseDown()
    {
        startPos = Camera.main.WorldToScreenPoint(transform.position);
        dist = transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, startPos.z));
    }

    void OnMouseDrag()
    {
        Vector3 lastPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, startPos.z);
        transform.position = Camera.main.ScreenToWorldPoint(lastPos) + dist;
    }
}

or this, if you prefer XZ plane:

public class MovementController : MonoBehaviour
{
    Vector3 startPos;
    Vector3 dist;

    void OnMouseDown()
    {
        startPos = Camera.main.WorldToScreenPoint(transform.position);
        dist = transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, startPos.y, Input.mousePosition.y));
    }

    void OnMouseDrag()
    {
        Vector3 lastPos = new Vector3(Input.mousePosition.x, startPos.y, Input.mousePosition.y);
        transform.position = Camera.main.ScreenToWorldPoint(lastPos) + dist;
    }
}

EDIT:

to control how much the position changes, change:

transform.position = Camera.main.ScreenToWorldPoint(lastPos) + dist;

to:

Vector3 targetPos = Camera.main.ScreenToWorldPoint(lastPos) + dist;
Vector3 dir = targetPos - transform.position;
float dist = dir.magnitude;
Vector3.Normalize(dir);
// change 1.0f to something else if you want:
transform.position += new Vector3(dir.x * dist * 1.0f, dir.y * dist * 1.0f, dir.z * dist * 1.0f);

and if you change dir.z * dist * 1.0f to dir.z * dist * 2.0f then you will move twice as much in Z direction.

Upvotes: 3

Related Questions