スマホゲームで最も重要な操作、それがタップと長押し(ロングプレス)です。
本記事では Unity 2022 以降/iOSを対象に、ワンタップ・長押し・マルチタッチをシンプルに実装する方法を網羅的に解説します。標準Input API・新Input System・UIイベントの3パターンを用意しているので、コピペであなたのプロジェクトに組み込めます!
この記事で分かること
- Unity標準Inputクラスでタッチ&長押しを判定する方法
- 0.5秒以上タッチしたら長押し とみなす汎用スクリプト(コピペOK)
- 新Input System(EnhancedTouch)でのマルチタッチ対応
- UIボタンでも長押しを取りたい場合のIPointerDownHandler / IPointerUpHandler実装
- iOS特有の注意点(Touch Delay/Homeインジケータ誤タップ対策 など)
Unity標準Inputクラスでタッチと長押しを取る
ワンタップ判定(最短コード)
・iOSでもGetMouseButtonはタッチをマウスとして扱うため動作します。
・Input.touchCountを使うとマルチタッチ数も取得可能。
if (Input.GetMouseButtonDown(0)) {
// タップ開始
}
if (Input.GetMouseButtonUp(0)) {
// タップ終了(指が離れた)
}
汎用ロングプレス検出スクリプト(0.5 秒以上)
- OnTapとOnLongPressにメソッドを登録するだけでOK。
- しきい値を変えれば「0.8秒でチャージショット」など応用自在。
using UnityEngine;
using System;
public class TouchLongPress : MonoBehaviour
{
public float threshold = 0.5f; // 長押し判定時間
public Action<Vector2> OnTap; // タップ時に呼ばれる
public Action<Vector2> OnLongPress; // 長押し時に呼ばれる
float _timer;
bool _isPressing;
void Update()
{
// 指を置いた瞬間
if (Input.GetMouseButtonDown(0))
{
_isPressing = true;
_timer = 0f;
}
// 指を離した瞬間
if (Input.GetMouseButtonUp(0))
{
if (_isPressing && _timer < threshold)
OnTap?.Invoke(Input.mousePosition); // 通常タップ
_isPressing = false;
}
// 長押し判定
if (_isPressing)
{
_timer += Time.deltaTime;
if (_timer >= threshold)
{
_isPressing = false; // 1回だけ発火
OnLongPress?.Invoke(Input.mousePosition);
}
}
}
}
新Input System+EnhancedTouchでマルチタッチ
パッケージを有効化
- Edit > Project Settings > PlayerでActive Input Handling = Bothを選択
- Window > Package ManagerからInput Systemを導入
サンプルコード
・FingerにはカスタムでwasLongPressedの拡張プロパティを用意してください。
・複数指で同時に長押し → 各指ごとにフラグ管理できるのがEnhancedTouchの強みです。
using UnityEngine;
using UnityEngine.InputSystem.EnhancedTouch;
using Finger = UnityEngine.InputSystem.EnhancedTouch.Finger;
public class MultiTouchLongPress : MonoBehaviour
{
const float THRESHOLD = 0.5f;
void OnEnable() => EnhancedTouchSupport.Enable();
void OnDisable() => EnhancedTouchSupport.Disable();
void Update()
{
foreach (Finger finger in Touch.activeFingers)
{
Touch touch = finger.currentTouch;
float heldSec = Time.time - touch.startTime;
if (touch.phase == TouchPhase.Ended && heldSec < THRESHOLD)
{
// シングルタップ
Debug.Log($"Tap pos:{touch.screenPosition}");
}
else if (heldSec >= THRESHOLD && !finger.wasLongPressed)
{
finger.wasLongPressed = true; // 拡張フィールドで済む
Debug.Log($"LongPress finger{finger.index}");
}
}
}
}
UIボタンで長押しを検出する(EventSystem経由)
・Time.unscaledDeltaTimeを使えばポーズ中(Time.timeScale=0)でも長押しを検出可能。
using UnityEngine;
using UnityEngine.EventSystems;
public class UILongPress : MonoBehaviour,
IPointerDownHandler, IPointerUpHandler, IPointerExitHandler
{
public float threshold = 0.5f;
float timer;
bool pressing;
public void OnPointerDown(PointerEventData eventData)
{
pressing = true; timer = 0;
}
public void OnPointerUp(PointerEventData _) => Reset();
public void OnPointerExit(PointerEventData _) => Reset();
void Update()
{
if (pressing && (timer += Time.unscaledDeltaTime) >= threshold)
{
pressing = false;
Debug.Log("UI LongPress!");
}
}
void Reset() => pressing = false;
}
iOS特有の落とし穴と対策
問題 | 原因 | 解決策 |
---|---|---|
Touch Delay (タップが遅延する) | iOS Safari/WebView 向けのヒットテスト遅延の名残 | Player Settings → Resolution & Presentation → Delay Touches を Never に設定 |
ホームインジケータ誤タップ | iPhone X 以降のジェスチャーバー | Player Settings → Hide Home Button on iPhone X を On Demand にする or ネイティブプラグインで prefersHomeIndicatorAutoHidden=true |
3D Raycast と UI の競合 | Physics.Raycast と EventSystem の入力がバッティング | EventSystem.current.IsPointerOverGameObject() で UI上か判定し、ゲーム側タッチを無視 |
まとめ
- 標準 Input APIで軽量実装 → 小規模プロジェクト向け
- 新Input System(EnhancedTouch)で本格マルチタッチ&デバイス横断
- UI イベント でボタン長押しもラクラク
- iOS固有の Touch Delay/ホームバー誤タップは Player Settingsで事前対策
これでワンタップから長押し・複数指まで、iOSのタッチ操作は完全攻略です。
自分のタイトル画面やゲームプレイ画面に合わせて、ぜひコピペ&カスタマイズしてみてください!