対戦カードゲーム開発ブログ 【2019年秋リリース(ios,android)】

【uGUI】カードドラッグをしてみよう

はじめに

こんにちは!Beyond the fieldアウトゲーム部分実装担当の鹿内です。
とある大学院に通いながら、Beyondの開発を進めています。
自己紹介記事

さて、皆さんは普段スマホゲームやったりしますか?
僕はシャドバ、デレステ、ミリシタ…結構色々やります 。 (デレP、ミリPの方がいたら是非同僚になりましょう。笑)

スマホゲームをやるとき何らかのカードをドラッグする、そんな瞬間は結構あると思います。
本記事ではBeyondにてカードドラッグをどのように実装したかを何回かに分けて、知見を共有していきたいと思います。

(本記事はカードドラッグ第一回目ということで、レベル的には「uGUI何それ美味しいの?」な方向けです。つよつよマンの皆さんはしばしお待ちを)

カードを動かす

Unityでのオブジェクトのドラッグとして、今回はuGUIにおける実装をしていきたいと思います。

まず適当なSceneのHierarchy上で右クリック、UI → Canvasを配置します。 そのCanvas直下にお好きなオブジェクトを置いてみてください。 僕は今回「アストラ・ヴォルフレア」でいきます。(めちゃカッコいいf:id:beyond-the-field-tcg:20190610212327p:plain

このオブジェクトをドラッグで動かすためにスクリプトを書きます。

using UnityEngine;
using UnityEngine.EventSystems;

public class CardDragger : MonoBehaviour, IDragHandler
{
    public void OnDrag(PointerEventData pointerEventData)
    {
        transform.position = pointerEventData.position;
    }
}

…なんとこれだけ。 OnDragはドラッグ中にカーソルが動くと呼び出されるので、その間オブジェクトの位置にドラッグ位置を代入します。
ではCardDragger.csをオブジェクトにアタッチして動かしてみましょう! Image from Gyazo

こいつ…動くぞ!
これを軸として、デッキメイキングにおけるカードドラッグっぽくしていきます。

コピーしたカードをドラッグ

デッキメイキングということで、例えばデッキに同種のカードが「×3」といった感じで入っているとします。 このときに先程の実装だけだと、そのカードを1枚だけ抜きたいときに全て付いてきてしまいますよね。
なのでドラッグしたいオブジェクトのコピーを作って、それをドラッグする機能を追加します。

実装方法はいろいろとあると思いますが、今回は以下の簡単な手順でやってみます。

  1. ドラッグし始めにカードを複製する
  2. ドラッグ中はコピーしたカードを移動させる
  3. ドラッグ終了時にコピーしたカードを消す

先程とは違い今回はドラッグし始め終了時の処理があります。
とは言ってもIBeginDragHandler, IEndDragHandlerインターフェースを継承するだけですが。

using UnityEngine;
using UnityEngine.EventSystems;

public class CardDragger : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
    private GameObject _cardResource; // Resourcesフォルダから読み込むPrefab用
    private GameObject _card; // 複製したカード

    private void Start()
    {
        // Prefabを読み込む
        _cardResource = Resources.Load("Prefabs/Card") as GameObject;
    }

    public void OnBeginDrag(PointerEventData pointerEventData)
    {
        // ドラッグし始めにカードを複製する
        _card = Instantiate(_cardResource, transform.parent, false);
    }

    public void OnDrag(PointerEventData pointerEventData)
    {
        // コピーしたカードを動かす
        _card.transform.position = pointerEventData.position;
    }

    public void OnEndDrag(PointerEventData pointerEventData)
    {
        // ドラッグ終わりにコピーしたカードを消す
        Destroy(_card);
    }
}

こんな感じでスクリプトに変更を加えます。
では動かしてみましょう! Image from Gyazo

ちゃんと動きましたね。
ほんの少しだけカードゲーム感が出たかな?
(実際の実装ではたくさんの機能・仕組みがあるため、上のコードとは違いUniRxを使ったりしています)

次回予告(僕が担当する記事)

次回はスクロールビューとカードドラッグの共存についての記事を書きます!(いつ出すかは未定
ではでは~