【Unity】格子状のマップをタッチできるようにしたい

課題

f:id:cacapon:20210820104354p:plain

Unityにて上図のような格子状のマップに

ポリオミノを設置していくパズルを考えている。


設置したポリオミノを再度持ち上げるために、

各マスを個別に判別するタッチ機能を設けたい。

解決法

絵の部分とは別に

格子状のタッチパネルを用意することで解決します。

手順としては下記の通り。

  1. 絵を準備する(ここではTilemapを使用)
    今回は下図の内7x7のマスが対象としています。
    f:id:cacapon:20210820104910p:plain

  2. 絵と同じ大きさになる、透明のGameObjectを準備する【①とする】
    f:id:cacapon:20210820105214p:plain

  3. 【①】にGridLayautGroupコンポーネントを追加する
    設定値は上図を参照してください

  4. 【①】の子オブジェクトとしてUI->Imageオブジェクトを追加する【②とする】

  5. 【②】にスクリプトをアタッチする。
    アタッチするスクリプトは「②にアタッチするスクリプトについて」を参照してください

  6. 【②】のイメージのColorのAの値を0にして透明にする。
    f:id:cacapon:20210820111721j:plain

  7. ②をマスの数だけ複製する。今回だと7x7 = 49個

  8. 複製した②の名前をそれぞれ00,01,02...06,10...,66に変更する
    f:id:cacapon:20210820113502p:plain

②にアタッチするスクリプトについて

ブログ用 各マスを感知するためのスクリプト

説明

大まかな動作について

各マスは、どの座標にいるのかそれぞれ知っており、

そのマスがタップされたら、その座標を起こしたいアクションに渡す

という事で、行いたい事を実現しています。


例えば、今回行いたかった、「ポリオミノを持ち上げたい」という場合

  1. 座標(x,y)のセルが一定時間タップされた

  2. 座標(x,y)を持ち上げるコマンドに渡す。

  3. 座標(x,y)と同じポリオミノはほかの座標にないか探す*1

  4. 該当するポリオミノを持ち上げる用のマップに移す。*2

といった流れで持ち上げるという動作を実現しました。

GridRayoutGroupについて

このコンポーネントが追加されたオブジェクトの子オブジェクトは

自動的に格子状に並ぶようになります。

今回はマスの大きさである16x16に合わせた後は、左上から順に並ぶようにしました。

スクリプトのOnPointerDown OnPointerUpについて

こちらはそれぞれIPointerDownHandler,IPointerUpHandlerのインターフェースで、

Downはタッチされたとき、Upはタッチが終わった時に呼ばれます。


このスクリプトでは、「長押しされたらピースを持ち上げる」というのを実装したかったため、

Downで時間計測を開始、

update側で監視している処理が有効になり、

一定時間経過したら持ち上げる処理を実行。

という流れになります。

00~66まで名付けた理由

スクリプトのAwake()中で名前から座標を設定している為です。

gameObject.name.Substring(x,x)が該当の箇所ですが、

これをprivateで宣言しているposに代入しています。


名前が変わったら動かなくなるので実装としては微妙かもしれません。

posをSerializefieldなどでインスペクターに公開して

各項目をそれぞれ設定するなど、他にやりようはありそうな感じはあります。


実際もっといいやり方はありそうです。

例えば、SetTileをそもそもタップで判定する方法があったりなど。

ただ、今回その方法が分からなかったため、

格子状の透明なタッチ領域を作り、座標で判別するような形に落ち着きました。

今回はここまで、それではまた。

*1:ここでは取り上げませんが、一意なIDで判定しています

*2:透明な7x7のマップがもう一つあり、片方に移すことで実現しています