【自作ゲーム開発19】ドラッグアンドドロップの実装【Unity】


注意
本記事で掲載されている動作の実装方法及びプログラムのソースコードは最適な方法ではない可能性があります。
今後不具合等が判明した場合には修正及び改良をおこなう可能性があります。
また今後自分で同機能を実装する場合の参考にする可能性もあるためソースコードだけではなく説明しつつ記事を進めていきます。

はじめに

Unityによる自作ゲーム開発進捗その19になります!

今回はドラッグアンドドロップを実装してみました。

6か所のキャラクター設置枠を作成して仮のキャラクターカード(ゲームオブジェクト)を入れ替え出来るようにしました。

負荷が高そうなため最適化のご意見等頂ければ即変更したい箇所です。

以下にソースコードを掲載します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class DragAndDrop : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler {
    [SerializeField]
    private GameObject[] m_area_list = new GameObject[6];

    [SerializeField]
    private GameObject[] m_character_list = new GameObject[7];

    private int m_start_number = 0, m_end_number = 0;

    private void Start() {
        CharacterSet();
    }

    public void OnBeginDrag(PointerEventData a_event_data) {
        m_start_number = 6;

        for(int l_loop = 0; l_loop < m_area_list.Length; l_loop += 1) {
            if(m_area_list[l_loop] == a_event_data.pointerEnter) {
                m_start_number = l_loop;
                break;
            }
        }
    }

    public void OnDrag(PointerEventData a_event_data) {
        m_character_list[m_start_number].transform.position = a_event_data.position;
    }

    public void OnEndDrag(PointerEventData a_event_data) {
        m_end_number = 88;

        for (int l_loop = 0; l_loop < m_area_list.Length; l_loop += 1) {
            if (m_area_list[l_loop] == a_event_data.pointerEnter) {
                m_end_number = l_loop;
                break;
            }
        }

        if(m_end_number != 88) CharacterChange(m_start_number, m_end_number);

        CharacterSet();
    }

    private void CharacterSet() {
        for (int l_loop = 0; l_loop < m_area_list.Length; l_loop += 1) {
            m_character_list[l_loop].transform.position = m_area_list[l_loop].transform.position;
        }
    }

    private void CharacterChange(int a_start, int a_end) {
        var l_object = m_character_list[a_start];
        m_character_list[a_start] = m_character_list[a_end];
        m_character_list[a_end] = l_object;
    }
}

/*
    [規則]
    p_ 外部アクセス
    m_ メンバー変数
    l_ ローカル変数
    a_ 引数
    e_ 列挙型

    [説明]

    [バージョン]
    2021-05-14 ドラッグアンドドロップによるキャラクター入れ替え

    [タスク]
*/

ドラッグアンドドロップ

[SerializeField]
private GameObject[] m_area_list = new GameObject[6];

[SerializeField]
private GameObject[] m_character_list = new GameObject[7];

【m_area_list】の配列には透明イメージがアタッチされているタップ可能なオブジェクトを格納しています。

【m_character_list】の配列には入れ替えるキャラクターカードのオブジェクトを格納しています。


private void CharacterChange(int a_start, int a_end) {
    var l_object = m_character_list[a_start];
    m_character_list[a_start] = m_character_list[a_end];
    m_character_list[a_end] = l_object;
}

【CharacterChange】関数では【m_character_list】配列の中身を入れ替えます。

入れ替える配列のインデックスは引数1と2を使用します。


public void OnBeginDrag(PointerEventData a_event_data) {
    m_start_number = 6;

    for(int l_loop = 0; l_loop < m_area_list.Length; l_loop += 1) {
        if(m_area_list[l_loop] == a_event_data.pointerEnter) {
            m_start_number = l_loop;
            break;
        }
    }
}

ドラッグ開始時に取得したマウス位置のオブジェクトと【m_area_list】内全てを比較して一致した場合はインデックス番号を変数に格納しています。

一致しなかった場合の変数初期値は6としています。


public void OnDrag(PointerEventData a_event_data) {
    m_character_list[m_start_number].transform.position = a_event_data.position;
}

ドラッグ中の処理はドラッグ開始時に取得したインデックスの【m_character_list】オブジェクトをマウス位置に追従させ続けます。

ドラッグ開始時に対応していないエリアをドラッグした場合の変数には6が入っているため【m_character_list】の6には透明なオブジェクトを入れてキャラクターカードが移動していないように見せています。


public void OnEndDrag(PointerEventData a_event_data) {
    m_end_number = 88;

    for (int l_loop = 0; l_loop < m_area_list.Length; l_loop += 1) {
        if (m_area_list[l_loop] == a_event_data.pointerEnter) {
            m_end_number = l_loop;
            break;
        }
    }

    if(m_end_number != 88) CharacterChange(m_start_number, m_end_number);

    CharacterSet();
}

ドラッグ終了時には開始時と同じようにマウス位置のオブジェクトと【m_area_list】内を比較してインデックスを取得します。

これにより開始時と終了時のエリアが変数に格納されているので【CharacterChange】関数で【m_character_list】の中身を入れ替えています。

変数の初期値を88にして終了位置がキャラクターカードに対応していなかった位置の場合は入れ替えはしないようにしています。

最後の【CharacterSet】関数はキャラクターカードの位置を更新する関数です。


動画


記事のリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です