Kunita
【Unity】タップとスワイプってどうやって分けてるの?【技術ブログ】
はい。毎日スマホゲーム作りを淡々と進めております。
今回、「スマホゲームを作るにあたって、多くの人がぶち当たる問題について記事にしたいなぁ」と思い立ちまして、このようなタイトルの記事を書かせていただきました。
実際、スマホの操作をUnity上で実装しようとして、
「タップとスワイプが上手く分けられない!」なんて悩みを持ってる方も多いと思います。
例えば2Dゲームでスワイプ=横移動、タップ=ジャンプなんて組み方をした際に、
スワイプと同時にジャンプしてしまうなんてこと、平気で起こるんですよね。
今回は、そういった問題の解決策を解説しちゃいます!
①そもそも、タップのコードって?
はい。スマホゲームのタップ・スワイプはPCで言う、左クリックとドラッグと一緒になります。
すなわちUnityで実装する場合は、
Input.GetMouseButtonDown(0)
ですね。これだけです。
でも、ちょっと待ってください。実は、ボタン系のコードって他にもありますよね?
Input.GetMouseButton(0)
Input.GetMouseButtonUp(0)
これらも左クリック(タップ)を表すコードになります。
ではこれらってどう違うのか、ということですが、実はとても簡単です。
Input.GetMouseButtonDown(0) //クリック(タップ)した瞬間
Input.GetMouseButton(0) //クリック(タップ)している間ずっと
Input.GetMouseButtonUp(0) //クリック(タップ)が終わり、ボタン(指)を離した瞬間
クリックもしくはタップをしている一連の動作を3つに切り分けてるんですね。
「一番上だけでよくない?」なんて思ったりもしますが、実は、これらを上手く使い分けることがタップとスワイプを分ける上で重要になります。
②タップをどう扱うか?
マリオのような2D横スクロールアクションで「タップでジャンプする」という場合を考えてみましょう。
この場合、1回だけジャンプするのだから、Input.GetMouseButtonDown(0) (タップした瞬間)、もしくはInput.GetMouseButtonUp(0) (タップが終わり、画面から指を離した瞬間)で良さそうです。
(ちなみにInput.GetMouseButton(0) (タップしている間ずっと)にしてしまうと、ジャンプを指が画面についている間、複数回ジャンプを実行してしまいます)
③スワイプをどう扱うか?
では、スワイプはと言うと、スワイプ動作中は指はずっと画面に張り付きっぱなしですよね?
それならば、もうInput.GetMouseButton(0)以外あり得ません。
これで割り振りが決まりましたね。
タップは、Input.GetMouseButtonDown(0) か Input.GetMouseButtonUP(0)
スワイプは、Input.GetMouseButton(0)
でも、ここで困った問題が、タップをどっちのコマンドで設定しても、スワイプの始めか終わりにタップされてしまうことになります。
マリオの例ですと、横移動前にジャンプか、横移動が終わった後にジャンプが入るわけです。
これは、「スワイプした際はジャンプを無効にする」というルールを付けることで解決します。
では、どうするかと言いますと、タップとスワイプの違いを上手く利用します。
タップする際は、指が画面に触れる時も、画面から話す時も座標は一緒ですよね?
逆にスワイプの際は絶対に指の位置が変わっているはずです。
つまり、update内にこんなコードを実装すればOKです。
//以下は宣言文
float FingerPosX0 //タップし、指が画面に触れた瞬間の指のx座標
float FingerPosX1 //タップし、指が画面から離れた瞬間のx座標
float FingerPosNow //現在の指のx座標
float PosDiff=0.5f //x座標の差のいき値。
//ここまで宣言文
void update()
{
if (Input.GetMouseButtonDown(0))
{
FingerPosX0 = Input.mousePosition.x;
}
if (Input.GetMouseButtonUp(0))
{
FingerPosX1 = Input.mousePosition.x;
}
if (Input.GetMouseButton(0))
{
FingerPosNow = Input.mousePosition.x;
}
//ジャンプの判断基準
if (Mathf.Abs(FingerPosX0 - FingerPosX1) < PosDiff)
{
Jump(); //別途定義したジャンプのメソッドを実行
}
//横移動の判断基準
if (FingerPosNow - FingerPosX0 >= PosDiff)
{
MoveToRight(); //別途定義した右方向移動のメソッドを実行
}
else if (FingerPosNow - FingerPosX0 >= -PosDiff)
{
MoveToLeft(); //別途定義した左方向移動のメソッドを実行
}
まず、タップした瞬間と指を離した瞬間のx座標を定義します。
タップ操作の際はいずれの座標もほぼ同じ筈なのでif文で両者の差が規程した数値(このスクリプト内では0.5)以下だった場合に限り、ジャンプを実施させることにします。
ちなみにゲームの設定に合わせ、PosDiffの値は好きに変えてOKです。
できるだけ長い距離をスワイプさせたり、ジャンプの感度を上げたい場合にはPosDiffを大きくすると良いでしょう。
そして、スワイプについては、画面に指が触れている間の座標を追わせます。
最初に指が触れた瞬間と現在の瞬間の指の位置の差をとり、その正負によって右移動・左移動の動作を分けてやれば大丈夫です。
以上、タップ・スワイプのスクリプトでした。