LoginSignup
4
5

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-02-25

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

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

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

サンプルコード

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

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)は画面をタップした瞬間 を表しています。(公式ドキュメントはこちら


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

この Input.mousePositionは、タップした位置の座標を示しています。(公式ドキュメントはこちら
そのタップした座標を、先に宣言した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を返します。(公式ドキュメントはこちら
つまり、タップしたまま指を動かしている間(=スワイプ?)ずっとif文以下が実行されるわけです。


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

Vector3 mousePosDiff = Input.mousePosition - preMousePos;

mousePosDiffは変数名の通り、1フレーム前の指の位置との差異のベクトルを表します。ベクトルの引き算です。
現在のフレームの座標:Input.mousePosition
1フレーム前の座標:preMousePos
とし、この2つを引き算することで、2つのフレームの差異のベクトル、つまり移動した「方向」を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を検知して、
それを繰り返すことで、移動している ということになります。

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

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5