見出し画像

【Unity】2Dオブジェクトにクリックとかドラッグをできるようにする

前回記事

https://note.com/woworora/n/nfc1765328c7a
Unityを積むことはや数か月。イベントの取り扱いすら忘れたので手っ取り早く忘備録を書く。
思い出しがてら、UIオブジェクトに実装したイベントコンポーネントを2Dに移植してみた。

基本のスクリプト

まずは任意の2Dオブジェクトに以下のスクリプトと2D Colliderをアタッチする。EventSystemの作成も忘れずに。

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


public class InteractiveObject: MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler, IBeginDragHandler, IDragHandler, IEndDragHandler, IDropHandler, IPointerDownHandler
{
    new public Transform transform; // オブジェクトのTransform

    protected virtual void Awake()
    {
        transform = GetComponent<Transform>();
    }

    public Action<InteractiveObject, PointerEventData> OnClickAction;
    public Action<InteractiveObject, PointerEventData> OnPointerEnterAction;
    public Action<InteractiveObject, PointerEventData> OnPointerExitAction;
    public Action<InteractiveObject, PointerEventData> OnBeginDragAction;
    public Action<InteractiveObject, PointerEventData> OnDragAction;
    public Action<InteractiveObject, PointerEventData> OnEndDragAction;
    public Action<InteractiveObject, PointerEventData> OnDropAction;
    public Action<InteractiveObject, PointerEventData> OnPointerDownAction;

    public void ResetAllActions()// すべてのイベントアクションを空のラムダ式にリセットする
    {
        OnClickAction = null;
        OnPointerEnterAction = null;
        OnPointerExitAction = null;
        OnBeginDragAction = null;
        OnDragAction = null;
        OnEndDragAction = null;
        OnDropAction = null;
        OnPointerDownAction = null;
    }

    public void OnPointerClick(PointerEventData eventData)
    {
        OnClickAction?.Invoke(this, eventData);
    }

    public void OnPointerEnter(PointerEventData eventData)
    {
        OnPointerEnterAction?.Invoke(this, eventData);
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        OnPointerExitAction?.Invoke(this, eventData);
    }

    public void OnBeginDrag(PointerEventData eventData)
    {
        OnBeginDragAction?.Invoke(this, eventData);
    }

    public void OnDrag(PointerEventData eventData)
    {
        OnDragAction?.Invoke(this, eventData);
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        OnEndDragAction?.Invoke(this, eventData);
    }

    public void OnDrop(PointerEventData eventData)
    {
        OnDropAction?.Invoke(this, eventData);
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        OnPointerDownAction?.Invoke(this, eventData);
    }
}

クリックとドラッグのイベント作成

今回は個別のスクリプトを書いて、それぞれアタッチすることで実装した。
オブジェクトに対する操作が常に同じなら、分かりやすくて管理しやすいかも。

// クリックしたらOnOffを切り替える。前回記事の機能
using System;
using UnityEngine;
using UnityEngine.EventSystems;

public class ExmSwitch : MonoBehaviour
{
    public InteractiveObject obj;

    void Start()
    {
        obj.OnClickAction = (obj, eventData) => buttonOn();
    }

    public void buttonOn()
    {
        obj.OnClickAction = (obj, eventData) => buttonOff();        
        Debug.Log("buttonOn");
    }
    public void buttonOff()
    {
        obj.OnClickAction = (obj, eventData) => buttonOn();
        Debug.Log("buttonOff");
    }
}
// Dragしたらマウスにオブジェクトを追従させる。離したら元の座標に戻る。
using System;
using UnityEngine;
using UnityEngine.EventSystems;

public class ExmDrag : MonoBehaviour
{
    public InteractiveObject obj;
    private Vector3 defaultPosition;

    void Start()
    {
        // 初期位置を保存
        obj.OnBeginDragAction = (obj, eventData) => setDefaultPosition();
        obj.OnDragAction = (obj, eventData) => drag(eventData);
        obj.OnEndDragAction = (obj, eventData) => resetPosition();
    }

    private void drag(PointerEventData eventData)
    {
        // マウス位置を取得してオブジェクトの位置を更新
        Vector3 mousePosition = Input.mousePosition;

        // マウス座標をワールド座標に変換
        mousePosition.z = Camera.main.WorldToScreenPoint(obj.transform.position).z; // 元のオブジェクトのZ座標を保持
        Vector3 worldPosition = Camera.main.ScreenToWorldPoint(mousePosition);

        // オブジェクトの位置を更新
        obj.transform.position = worldPosition;
    }

    private void setDefaultPosition()
    {
        defaultPosition = obj.transform.position;
    }

    private void resetPosition()
    {
        obj.transform.position = defaultPosition;
    }
}


inspecterはこんな感じ


いいなと思ったら応援しよう!