【Unity】タップした方向にキャラを移動させる

Unityでスマホゲーム（主に2Dゲームを想定）を作ってて、
タップやスワイプでキャラを動かしたい時の実装です。

ただ、タップした「位置」にキャラを移動させてしまうと、
自分の指が邪魔してキャラが見えなくなってしまいます。

よって、今回はタップした「方向」にキャラを移動させる実装について書きます。
つまり、移動する「方向」だけをタップした位置から検知します。
移動の「大きさ」については、1つの変数の値を変えるだけの実装になっているので、楽チンです。


#サンプルコード
以下のコードを写して、そのスクリプトを動かしたいキャラのGameObjectにアタッチすれば、とりあえず動きます。
もしかしたら、上下左右ではなく、上下と奥行きにキャラが移動してしまうかもしれませんが、下の解説を読んでいけば解決するはずです。

```C#:Sample.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Sample : MonoBehaviour {

    float speed = 5.0f;
    Vector3 preMousePos;
	
	void Update () {
        Move();
	}

    void Move()
    {
        if (Input.GetMouseButtonDown(0))
        {
            preMousePos = Input.mousePosition;
        }
        if (Input.GetMouseButton(0))
        {
            Vector3 mousePosDiff = Input.mousePosition - preMousePos;
            preMousePos = Input.mousePosition;
            Vector3 newPos = this.gameObject.transform.position + new Vector3(mousePosDiff.x / Screen.width, 0, mousePosDiff.y / Screen.height) * speed;

            this.transform.position = newPos;
        }
    }
}

```

#解説
##変数宣言
```
float speed = 5.0f;
Vector3 preMousePos;
```
`speed` は移動の「大きさ」を表す変数です。
`speed`の値を大きくすれば、タップして指を少し動かしただけで、キャラは大きく移動し、
小さくすれば、指を動かしてもキャラは少ししか移動しません。値を変えて動かしてみれば、実感できると思います。

`preMousePos`は、(x,y,z)座標を示す3次元ベクトルです。
1フレーム前にタップしていた座標を保存しておく変数です。詳しくは、後ほど解説します。


##Move()関数
###画面をタップした瞬間
```
 if (Input.GetMouseButtonDown(0))
 {
   preMousePos = Input.mousePosition;
 }
```
`Input.GetMouseButtonDown(0)`は画面をタップした瞬間 を表しています。（公式ドキュメントは[こちら](https://docs.unity3d.com/ja/current/ScriptReference/Input.GetMouseButtonDown.html)）

---
タップした瞬間に以下の処理をします。
`preMousePos = Input.mousePosition;`

この `Input.mousePosition`は、タップした位置の座標を示しています。（公式ドキュメントは[こちら](https://docs.unity3d.com/ja/2017.4/ScriptReference/Input-mousePosition.html)）
そのタップした座標を、先に宣言した`preMousePos`というVector3型の変数に格納しています。

###画面をタップして指を移動している間
```
if (Input.GetMouseButton(0))
{
  Vector3 mousePosDiff = Input.mousePosition - preMousePos;
  preMousePos = Input.mousePosition;
  Vector3 newPos = this.gameObject.transform.position + new Vector3(mousePosDiff.x / Screen.width, 0, mousePosDiff.y / Screen.height) * speed;

  this.transform.position = newPos;
}
```
`Input.GetMouseButton(0)`はタップしている間ずっとtrueを返します。（公式ドキュメントは[こちら](https://docs.unity3d.com/ja/2017.4/ScriptReference/Input.GetMouseButton.html)）
つまり、タップしたまま指を動かしている間（＝スワイプ？）ずっとif文以下が実行されるわけです。

---
if文内の処理についてです。

`Vector3 mousePosDiff = Input.mousePosition - preMousePos;`

`mousePosDiff`は変数名の通り、1フレーム前の指の位置との差異のベクトルを表します。ベクトルの引き算です。
現在のフレームの座標：`Input.mousePosition`
1フレーム前の座標：`preMousePos`
とし、この２つを引き算することで、２つのフレームの差異のベクトル、つまり移動した「方向」を`mousePosDiff`という変数に格納しています。

---
`preMousePos = Input.mousePosition;`

こちらで、前節の 画面をタップした瞬間 と同じ処理をします。
つまり、
方向(mousePosDiff)を検知 → preMousePosを更新
をフレームごとに絶え間なく繰り返していることになります。

---
`Vector3 newPos = this.transform.position + new Vector3(mousePosDiff.x / Screen.width, 0, mousePosDiff.y / Screen.height) * speed;`

この行で、現在のキャラの位置（`this.transform.position`）に対して、
先ほど取得した指が移動した方向（`mousePosDiff`）を用いて、移動先の座標`newPos`を定義しています。

※座標は、Screen.widthとScreen.heightで割ることで画面に対応させてます。
※この例ではx座標とz座標を移動させていますが、自身のゲームに合わせてどの座標を動かすかは適宜変更してください。`(mousePosDiff.x / Screen.width, 0, mousePosDiff.y / Screen.height)`の部分。
※speed の値を変更することで移動の大きさを変更できます。

---
`this.transform.position = newPos;`

定義した`newPos`を自分の今の座標`this.transform.position`に代入することで、実際に移動をします。

---

以上の処理を、タップして指を動かしている間ずっと実行し続けることで、移動します。
つまり、1フレームごとに、
現在のタップしている座標`Input.mousePosition` と
前のフレームでタップしていた座標`preMousePos `から
移動した方向`mousePosDiff`を検知して、
それを繰り返すことで、移動している ということになります。


もう少しわかりやすく書きたかったんですが、
文面だけだとかなりわかりづらくなってしまいました。。
とりあえず、サンプルコードを写せば動きます。。