iOS対応

【Unity×iOS】タッチとドラッグを正しく区別する方法|スワイプ暴発を防ぐ

タップ操作をしたつもりがキャラクターが動いたり、ドラッグしたいだけなのにボタンが押されてしまう……。
UnityでiOS向けアプリやゲームを作ると、こうしたタッチとドラッグの誤動作に悩まされることがよくあります。
この記事では、タッチとドラッグを正しく区別するシンプルな実装方法を解説します。
コピペでそのまま使えるスクリプトも紹介しますので、ぜひプロジェクトに取り入れてみてください!

この記事で分かること

  • タッチとドラッグを区別しないと起こる問題
  • 距離のしきい値(スレッショルド)を使った正しい区別方法
  • コピペOK!シンプルなタッチ・ドラッグ判定スクリプト
  • iOSアプリ開発で気をつけるポイント(タッチ遅延や誤反応防止)

なぜタッチとドラッグを区別しないと危ないのか?

Unityの標準Input(Input.GetMouseButtonDownやInput.GetTouch)は非常にシンプルに使えますが、タッチとドラッグを厳密に区別する仕組みはありません
そのため、特にiOSアプリでは次のような問題が起こりやすくなります。

  • ほんの少し指が動いただけでドラッグ扱いされてしまう
  • ボタンを押したつもりがキャラクター移動が始まる
  • 意図しない方向にスワイプ処理が走る

ユーザーにとって、「触っただけで動く」現象はストレスです。
これを防ぐには、一定以上の指の移動があったときのみドラッグと認識する実装が重要になります。

タッチとドラッグを区別する基本設計

タッチとドラッグの区別はとてもシンプルにできます。
基本はこの3ステップです。

  1. タッチ開始時の指の位置を記録する
  2. 指を動かしている間に、現在位置との差を計算する
  3. 設定した距離(しきい値)を超えたらドラッグと認識する

【コピペOK】距離しきい値でドラッグを検出するサンプルコード

以下に、すぐに使えるタッチ/ドラッグ判定スクリプトを紹介します!

using UnityEngine;
using System;

public class TouchDragDetector : MonoBehaviour
{
    public float dragThreshold = 20f; // ピクセル単位のしきい値
    private Vector2 startTouchPos;
    private bool isDragging;

    public Action<Vector2> OnTap;      // 通常タップ(ドラッグしなかった)
    public Action<Vector2> OnDragStart; // ドラッグ開始時
    public Action<Vector2> OnDragging;  // ドラッグ中
    public Action<Vector2> OnDragEnd;   // ドラッグ終了時

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            startTouchPos = Input.mousePosition;
            isDragging = false;
        }

        if (Input.GetMouseButton(0))
        {
            if (!isDragging)
            {
                if (Vector2.Distance(Input.mousePosition, startTouchPos) > dragThreshold)
                {
                    isDragging = true;
                    OnDragStart?.Invoke(Input.mousePosition);
                }
            }
            else
            {
                OnDragging?.Invoke(Input.mousePosition);
            }
        }

        if (Input.GetMouseButtonUp(0))
        {
            if (isDragging)
            {
                OnDragEnd?.Invoke(Input.mousePosition);
            }
            else
            {
                OnTap?.Invoke(Input.mousePosition);
            }
        }
    }
}

このスクリプトの特徴

  • タッチだけならOnTapが呼ばれる
  • ドラッグに切り替わった瞬間にOnDragStart
  • ドラッグ中は毎フレームOnDragging
  • 指を離したらOnDragEnd

つまり、タップとドラッグのすべてをきれいに区別できる設計です!

よくあるバグと防止テクニック

タッチを認識しない(iOS特有)

  • タッチ遅延 (Delay Touches) が影響する場合があります。
    → Player Settings → “Delay Touches” を「Never」に設定しておきましょう。

フレームレート依存でしきい値が不安定

  • 移動距離だけでなく、時間速度を組み合わせるとさらに精度が上がります。
  • ただし、普通のアクションゲームなら距離だけで十分です。

しきい値が厳しすぎてドラッグできない

float screenRatio = Screen.dpi / 160f;
dragThreshold = 20f * screenRatio; // 動的しきい値
  • iPhoneの画面サイズを考慮して、しきい値20〜30ピクセルがちょうどよいバランスです。
  • 高解像度端末ではスクリーン比率に応じて自動補正するとベター。

まとめ

  • タッチとドラッグは必ず距離しきい値で区別しよう
  • 指が少し動いただけならタップ、明確に動いたらドラッグと認識
  • コピペOKスクリプトを活用すれば、タッチ誤動作を完全に防止できる
  • iOS特有のタッチ遅延設定(Delay Touches)にも注意!

ユーザーにストレスを与えないスマホアプリは、タッチ体験の質で差がつきます。
ぜひこの記事のテクニックを、あなたのUnity×iOSプロジェクトに活かしてください!