使图像在两个可滚动之间可拖动

时间:2017-12-27 08:37:25

标签: c# unity3d coordinate-transformation

我有两个不同的小组:

panels

这是树:

tree

在这些面板中,我希望用户能够对左侧的图像进行陈词滥调,并将其拖动到右侧。

你可以找到大量的Unity" basic" UI dragndrop教程,但它们都是一样的:您可以在同一面板中的元素之间拖放。

我的问题是它们位于不同的面板中,所以我无法轻易地从一个面板拖动到另一个面板。

现在我只是想让拖拽原则在PanelBoatsToDrag 内部工作:能够点击Image,并能够拖动它进入 PanelBoatsToDrag

每个Image都是由预制件制成的。我已经为该预制件添加了一个DragHandler.cs脚本文件,它应该处理它。这是:

public class DragHandler : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{

    public static GameObject itemBeingDragged;
    private Vector3 startPosition;

    public void OnBeginDrag(PointerEventData eventData)
    {
        itemBeingDragged = gameObject;
        startPosition = transform.position;
        Debug.Log("OnBeginDrag\n" +
            "eventData = " + eventData +
            "\nInput.mousePosition = " + Input.mousePosition +
            "\nCamera.main.ScreenToWorldPoint(Input.mousePosition) = " +
            Camera.main.ScreenToWorldPoint(Input.mousePosition));
    }

    public void OnDrag(PointerEventData eventData)
    {
        transform.position = Input.mousePosition;
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        itemBeingDragged = null;
        transform.position = startPosition;
        Debug.Log("OnEndDrag");
    }
}

OnDrag(PointerEventData eventData)代码根本不起作用。我需要将鼠标坐标转换为被点击的Image的局部坐标,并将其指定给图像。如何使这项工作?

2 个答案:

答案 0 :(得分:1)

Unity还支持方法OnDrop()。如果我是你,我会这样接近它。在开始拖动OnBeginDrag()时,你应该做两件事:通过将其父级设置为PanelMiddle来将对象移动到层次结构中更高的位置,以便将其绘制在其他所有内容上this.GetComponent<CanvasGroup>().blocksRaycasts = false;,这样您就可以赢得&#39;光线投射到它。 之后应该很简单:

public void OnDrop(PointerEventData eventData)
{
GameObject dropedItem = eventData.pointerDrag.GetComponent<GameObject>();

if (isEmpty) // you have space for this object
{

  dropedItem.transform.SetParent(this.transform);
  dropedItem.transform.position = //set to any position you need
  dropedItem.GetComponent<CanvasGroup>().blocksRaycasts = true; //so you can pick this item again
}
else
{
  //return it to old position and to old parent
}
}

方法OnDrop()应附加到面板或您要将项目拖动到的某种插槽。

答案 1 :(得分:0)

我是这样做的,我让我班上唯一重要的部分在这里:

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class DragHandler : MonoBehaviour,
    IBeginDragHandler, IDragHandler, IEndDragHandler
{
    public void OnDrag(PointerEventData eventData)
    {
        CanvasScaler scaler = GetComponentInParent<CanvasScaler>();
        Vector3 i_scale = itemBeingDragged.transform.localScale;
        RectTransform rt = itemBeingDragged.GetComponent<RectTransform>();
        Rect r = rt.rect;
        /**
         * Explanation: to center the object we need its width+height:
         * Resize width to the current scale = r.width * i_scale.x 
         * Divide by 2 to get the center we have: (r.width * i_scale.x / 2)
         * Same for y.
         * 
         * Calculate the coords of the mouse proportional to the screen scale:
         */
        rt.anchoredPosition = new Vector2(
            (Input.mousePosition.x * scale_x) - (r.width * i_scale.x / 2),
            (Input.mousePosition.y * scale_y) - (r.height * i_scale.y / 2));
        // everybody tells me to apply this but it doesn't work:
        // itemBeingDragged.GetComponent<CanvasGroup>().blocksRaycasts = true;
    }

}