如何使用OnMouseDrag在屏幕上拖动对象?

时间:2019-06-03 22:16:47

标签: c# unity3d

尝试做2D和3D。我希望播放器单击并拖动对象以将其堆叠。我尝试从视频复制和粘贴代码,但仍然无法正常工作。

更新!现在它可以工作了,但是它可以将物体传送到远离屏幕的地方。我希望播放器能够平滑地单击并拖动对象。

到目前为止的代码:

using UnityEngine;
using System.Collections;

public class DragObject : MonoBehaviour
{
    private float deltax, deltay;


    private void OnMouseDown()
    {
        deltax = 1f;//Camera.main.ScreenToWorldPoint(Input.mousePosition).x - transform.position.x;
        deltay = 1f; //Camera.main.ScreenToWorldPoint(Input.mousePosition).y - transform.position.y;
    }

    private void OnMouseDrag()
    {
        Vector2 currentTouchPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        transform.position = new Vector2((Input.mousePosition).x - deltax, (Input.mousePosition.y) - deltay);
    }
}

2 个答案:

答案 0 :(得分:1)

完全不清楚您要解决的确切问题是什么,您显然需要提供更多信息并更好地描述问题。但我会尽力提供帮助。

要获取鼠标位置,您需要使用:

Input.mousePosition

如果您需要在二维坐标中定位鼠标,则可以使用以下方法:

Vector2 currentTouchPos = mainCamera.ScreenToWorldPoint(Input.mousePosition);

答案 1 :(得分:0)

此方法不管您的相机类型或相机在帧之间的移动方式如何都有效

首先,当首次单击对象时,获取与照相机方向垂直的对象所在的平面:

Plane dragPlane = new Plane(Camera.main.transform.forward, transform.position);

然后,从鼠标所在的位置获取从相机发出的光线:

Ray camRay = Camera.main.ScreenPointToRay(Input.mousePosition);

使用Plane.Raycast找出射线相交的位置:

float enter = 0.0f;
if (dragPlane.Raycast(camRay, out enter)) 
{
    Vector3 fingerPosition = camRay.GetPoint(enter);

这会给您在世界空间中的位置,您可以在其中考虑手指当前所在的位置。只需将对象放在这里:

transform.position = fingerPosition;

总共看起来可能像这样:

void OnMouseDrag()
{
    Plane dragPlane = new Plane(Camera.main.transform.forward, transform.position);
    Ray camRay = Camera.main.ScreenPointToRay(Input.mousePosition);
    float enter = 0.0f;
    if (dragPlane.Raycast(camRay, out enter)) 
    {
        Vector3 fingerPosition = camRay.GetPoint(enter);
        transform.position = fingerPosition;
    }
}

不需要OnMouseDown

另一种方法是跟踪fingerPosition随时间的变化,并Translate基于此变化。在世界单位中保持尽可能多的数学变得容易:

Vector3 prevFingerPosition = Vector3.zero;

// Same code as before but we use it in different places so it goes in its own method.
// If the Raycast fails, return a decent guess.
private Vector3 GetMouseOnPositionInWorldSpace() 
{
    Plane dragPlane = new Plane(Camera.main.transform.forward, transform.position);
    Ray camRay = Camera.main.ScreenPointToRay(Input.mousePosition);
    float enter = 0.0f;
    if (dragPlane.Raycast(camRay, out enter))
    {
        return camRay.GetPoint(enter);
    }

    return prevFingerPosition;
}

void OnMouseDown()
{
    prevFingerPosition = GetMouseOnPositionInWorldSpace();
}

void OnMouseDrag()
{
    Vector3 fingerPosition = GetMouseOnPositionInWorldSpace();
    transform.Translate(fingerPosition-prevFingerPosition);
    prevFingerPosition = fingerPosition;
}

此外,只需将其保留为void OnMouseDrag()void OnMouseDown(),不要包含private,以避免Unity无法找到方法的问题。

使用OnMouseDrag处理周围的对象背后的问题是,如果光标移动得太快,它可以在单个帧的范围内移出对象,并且会“掉落”对象。

如果不希望这样,您可能希望将bool中的true设置为OnMouseDown,以记住该对象已被单击并将逻辑移出{{1} }到OnMouseDrag中,如果Updatebool,它可以做自己的事情。释放鼠标后,将true设置回bool