使用鼠标拖动时,图像会跳到其中心点

时间:2015-07-11 05:46:08

标签: c# unity3d drag-and-drop draggable drag

希望有人能快速回答这个问题,因为我无法弄明白这一点。我希望能够在没有跳跃的情况下从图像上的任何位置拖动图像,而不是让图像跳到鼠标光标上。我知道它与在图像上引用鼠标位置或将图像的原点重新设置到鼠标位置有关,但我不知道如何编码它。有没有人这样做过?使用C#。

Vector3 partsPanelScale;
public Vector3 buildPanelScale;

public Transform placeholderParent = null;
public Transform parentToReturnTo = null;

GameObject placeholder = null;

public GameObject animalPart;

public GameObject trashCan; 
public GameObject partsPanel;
public GameObject partsWindow;
GameObject buildBoard;
GameObject dragLayer;

private float _mX; // holds current eventData.position.x
private float _mY; // holds current eventData.position.y
private float _pmX;// holds previous eventData.position.x
private float _pmY;// holds previous eventData.position.y

void Start ()
{
    dragLayer = GameObject.FindGameObjectWithTag("DragLayer");
    buildBoard = GameObject.FindGameObjectWithTag("Board");
    partsPanel = GameObject.FindGameObjectWithTag("Parts");
    partsWindow = GameObject.FindGameObjectWithTag("PartsWindow");
    trashCan = GameObject.FindGameObjectWithTag("Trash");
}

#region IPointerClickHandler implementation

public void OnPointerClick (PointerEventData eventData)
{
    if(transform.parent.gameObject == buildBoard)
    {
        transform.SetAsLastSibling();
    }
}

#endregion

#region IBeginDragHandler implementation

public void OnBeginDrag (PointerEventData eventData)
{
    // each frame updates the current position of the mouse.
    _mX = eventData.position.x;
    _mY = eventData.position.y;

    // create placeholder gap and hold correct position in layout
    placeholder = new GameObject();
    placeholder.transform.SetParent(transform.parent);
    placeholder.transform.SetSiblingIndex(transform.GetSiblingIndex());

    if(transform.parent.gameObject == partsPanel)
    {
        partsPanelScale = transform.localScale;
    }

    parentToReturnTo = transform.parent;                                    // store current parent location
    placeholderParent = parentToReturnTo;                                   // set placeholder gameobject transform

    GetComponent<CanvasGroup>().blocksRaycasts = false;                     // turn off image raycasting when dragging image in order to see what's behind the image            
}

#endregion

#region IDragHandler implementation

float distance = 0;



public void OnDrag (PointerEventData eventData)
{

    // Divided the difference by 6 to reduce the speed of dragging.
    transform.position = new Vector3
        (
            (_pmX - _mX)/6 + transform.position.x,
            (_pmY - _mY)/6 + transform.position.y,
            distance
            );

    // Vector3 mousePosition = new Vector3(eventData.position.x, eventData.position.y, distance);
    // Vector3 objPosition = Camera.main.ViewportToScreenPoint(mousePosition);
    // transform.position = mousePosition;                                  // set object coordinates to mouse coordinates

    if(transform.parent.gameObject == partsPanel)
    {
        transform.SetParent(dragLayer.transform);                           // pop object to draglayer to move object out of partsPnael
    }

    if(transform.parent.gameObject == buildBoard)
    {
        // Constrain drag to boundaries of buildBoard Code
    }
}

#endregion

#region IEndDragHandler implementation

public void OnEndDrag (PointerEventData eventData)
{
    // end of the drag. set the previous position.
    _pmX = _mX;
    _pmY = _mY;

    transform.SetParent(parentToReturnTo);                                  // Snaps object back to orginal parent if dropped outside of a dropzone
    transform.SetSiblingIndex(placeholder.transform.GetSiblingIndex());     // Returns card back to placeholder location

    GetComponent<CanvasGroup>().blocksRaycasts = true;                      // turn Raycast back on
    Destroy(placeholder);                                                   // kill the placeholder if object hits a drop zone or returns to parts panel

    if(transform.parent.gameObject == buildBoard)
    {
        // Debug.Log ("Your sprite is now on the " + transform.parent.name);

        transform.localScale = buildPanelScale;
        transform.SetAsLastSibling();                                       // always place last piece on top
    }

    if(transform.parent.gameObject == partsPanel)
    {
        transform.localScale = partsPanelScale;
    }
}

#endregion

1 个答案:

答案 0 :(得分:1)

要正确拖动,您需要鼠标的上一个当前位置。

因为每次移动鼠标时,Image应该从其先前位置移动一点(在x和y坐标处)。

如果您只是使用当前位置并直接将其设置为图像,则会将跳转到屏幕上。

您必须通过获取先前和当前位置(x2 - x1y2 - y1)的差异来转换图像转换。然后将最终转换设置为图像转换。

您还需要MouseOver个事件来更新职位。 (或MouseMove

private double _mX; // holds current eventData.position.x
private double _mY; // holds current eventData.position.y
private double _pmX;// holds previous eventData.position.x
private double _pmY;// holds previous eventData.position.y

// each frame updates the current position of the mouse.
private void MouseOver(PointerEventData eventData)
{
    _mX = eventData.position.x;
    _mY = eventData.position.y;
}

public void OnDrag (PointerEventData eventData)
{
    transform.position = new Vector3D((_pmX - _mX)/6 + transform.position.x,
                                      (_pmY - _mY)/6 + transform.position.y, distance);
    // Divided the difference by 6 to reduce the speed of dragging.

    //...

    // end of the drag. set the previous position.
    _pmX = _mX;
    _pmY = _mY;
}

请注意,我使用过的类名和事件可能与unity3d不同。

如果您从右向左拖动但图片从左向右移动,则将_pmX - mX替换为_mX - _pmX

如果您从上到下拖动但图片从下往上拖动,请将_pmY - mY替换为_mY - _pmY