Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
10
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

@divideby_zero

uGuiでDrag And Drop処理

こんな感じになります

http://dividebyzero.sakura.ne.jp/DragAndDrop/index.html
※Unity5.2.2f1でWebGL出力 読み込みにそこそこ時間がかかるので注意。

参考に視聴したもの

https://www.youtube.com/watch?v=c47QYgsJrWc
https://www.youtube.com/watch?v=bMuYUOIAdnc
https://www.youtube.com/watch?v=P66SSOzCqFU
https://www.youtube.com/watch?v=AM7wBz9azyU

まぁ、これらを見ると「意外と簡単だな?」ということはわかるわけなのですが。

足りないと思ったのは

  • ドラッグしようとした瞬間、ポインタの位置に瞬間移動するのが気に食わない → ちゃんと相対位置取っておけば良いのでは。
  • 入れ替えアニメーションとか付けたい → 簡単なUpdateで出来るのでは。

ということで作ってみました。

ドラッグされる方

DragObject.cs
using UnityEngine;
using UnityEngine.EventSystems;

[RequireComponent(typeof(CanvasGroup))]
public class DragObject : MonoBehaviour ,IDragHandler,IBeginDragHandler,IEndDragHandler
{
    public static DragObject dragObject;
    public Transform parentTransform;
    private Vector3 tapRefPosition;
    private CanvasGroup canvasGroup;
    private Transform canvasTransform;

    public CanvasGroup CanvasGroup { get { return canvasGroup ?? (canvasGroup = gameObject.AddComponent<CanvasGroup>()); }}
    public Transform CanvasTransform { get { return canvasTransform ?? (canvasTransform = GameObject.Find("Canvas").transform); } }

    public void OnBeginDrag(PointerEventData eventData)
    {
        tapRefPosition = (Vector2)transform.position - eventData.position;
        dragObject = this;
        parentTransform = transform.parent;
        transform.SetParent(CanvasTransform);
        CanvasGroup.blocksRaycasts = false;
        CanvasGroup.alpha = 0.5f;
    }

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

    public void OnEndDrag(PointerEventData eventData)
    {
        if (transform.parent == canvasTransform)
        {
            transform.SetParent(parentTransform);
        }
        dragObject = null;
        CanvasGroup.blocksRaycasts = true;
        CanvasGroup.alpha = 1.0f;
    }

    public void Update()
    {
        if (dragObject == null)
        {
            transform.localPosition -= transform.localPosition / 3.0f;
        }
    }
}

ポイントはonBeginDragでドラッグが始まる瞬間に、実際の位置とドラッグ開始位置の差分をtapRefPositionに確保している
tapRefPosition = (Vector2)transform.position - eventData.position;
と、OnDrag中はその差分tapRefPositionを加味して
transform.position = Input.mousePosition + tapRefPosition;
で実際にドラッグしている処理。

そして、Updateで、transform.localPositionを0にイーズアウトで近づける
transform.localPosition -= transform.localPosition / 3.0f;
です。

ドロップされる方

DropTarget.cs
using UnityEngine;
using UnityEngine.EventSystems;

public class DropTarget : MonoBehaviour ,IDropHandler{
    public GameObject Item
    {
        get
        {
            if (transform.childCount > 0)
            {
                return transform.GetChild(0).gameObject;
            }
            return null;
        }
    }

    public void OnDrop(PointerEventData eventData)
    {
        if (Item == null)
        {
            DragObject.dragObject.transform.SetParent(transform);
        }
        else
        {
            Item.transform.SetParent(DragObject.dragObject.parentTransform);
            DragObject.dragObject.transform.SetParent(transform);
        }
    }
}

こちらは特筆することはなく、DropされたDropObjectのParentをセットしたり、交換したりしているだけです。
前述したDropObjectのtransform.localPosition -= transform.localPosition / 3.0f;の処理によって、Parentを差し替えるだけでアニメーション付きで移動をするのでラクチンです。

足りてない所

  • Drag中のObjectは一番上に来て欲しいので、無理やり"Canvas"の名前でCanvas探してParentを変更している処理がありますが、名前変更してたら終わるね。 いくらでも手はあると思いますがぱっといい手が思いつかなかったのでペンディングしてます。

もっとuguiのノウハウが貯まるといいなぁ。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
10
Help us understand the problem. What are the problem?