【Unity】WebGLでピンチズームが効かない原因と解決法|touch-action:none一行で直る

投稿日: 2026年6月23日(2026年10月5日更新)
対象読者: Unity WebGLをスマホ対応させていて、2本指ピンチが効かずに困っているエンジニア

不具合内容

Unity WebGLをスマホのブラウザで開くと、2本指のピンチズームが効かない。3Dモデルは拡大されず、代わりにページ全体がズームしてしまう。1本指のスワイプ(回転)は正常に動く。

原因

  • スマホのブラウザが2本指のタッチを「ページのピンチズーム」として先に処理し、canvasまでタッチが届かない。Unityから見ると Input.touchCount が2にならない

解決方法

  • Unity WebGLの描画先 #unity-canvas に、CSSで touch-action: none; を1行足す。C#側の修正は要らない
  • viewport の user-scalable=no は、ページ全体のズームを禁止する設定で、要素の上のジェスチャの扱いを決めるものではない

動作環境

項目 内容
Unity 6000.0.58f2
(WebGLビルド)
対象 スマホのブラウザ
での2本指タッチ
修正箇所 PoseMirror の app.css
(#unity-canvas)

解決方法の詳細:canvas にtouch-action: none を指定する手順

2本指のタッチが Unity に届くようにする手順を説明し、そのあとに不具合の再現手順を載せます。

手順1:#unity-canvas のスタイルを書いているCSS を開く

Unity WebGLは、index.html の中の <canvas id="unity-canvas"> に3Dを描画します。このcanvasのスタイルは、Unity標準のWebGLテンプレートなら TemplateData/style.css に書かれています(Unity 6000.0.58f2 の Default テンプレートで確認)。

/* Unity標準テンプレートの TemplateData/style.css(抜粋) */
#unity-canvas { background: {{{ BACKGROUND_COLOR }}} }
.unity-mobile #unity-canvas { width: 100%; height: 100% }

どのテンプレートが使われるかは、Unityの「Edit → Project Settings → Player」でWebGLのタブを開き、「Resolution and Presentation」の「WebGL Template」で決まります。

UnityのProject SettingsのPlayer、Webのタブ。Resolution and Presentationを開いた中にWebGL Templateがあり、Default・Minimal・PWAから選べる

ビルド後のフォルダを直接編集すると、次のビルドで上書きされて消えます。自前のWebGLテンプレート(Assets/WebGLTemplates/テンプレート名/)を使っている場合はそちらのCSSを、PoseMirror のようにビルドを別のページに埋め込んでいる場合は、そのページのCSSを編集します。

手順2:touch-action: none; を1行足す

#unity-canvas のスタイルに touch-action: none; を追加します。C#側の修正は要りません。

#unity-canvas {
  width: 100% !important;
  height: 100% !important;
  display: block;
  object-fit: contain;       /* 歪みを防止 */
  touch-action: none;        /* モバイルのピンチをUnityへ渡す(ページズームに奪わせない) */
}

touch-action: none; は、この要素の上ではブラウザがスクロールもピンチズームもしない、という指定です。ブラウザがジェスチャを横取りしなくなるので、2本指のタッチが canvas を通って Unity に届きます。

手順3:公開し直す

CSSを直したファイルを、Unity WebGLを公開している場所(Firebase Hosting など)へアップロードし直します。スマホのブラウザはCSSをキャッシュしていることがあるので、確認前に再読み込みします。

確認1:スマホで2本指ピンチをして、3Dだけがズームする

スマホのブラウザでページを開き、3Dの上で2本指ピンチをします。ページ全体ではなく3Dモデルだけが拡大・縮小されれば成功です。Unity 側では Input.touchCount が 2 になり、下の「再現1」の C# のコードが動きます。

PoseMirror では、この1行を #unity-canvas に足しただけでピンチズームが効くようになりました。

参考:viewport のuser-scalable=noとは役割が違う

ページのズームを止めたいなら、viewport の user-scalable=no でもよいのでは、と思うかもしれません。この2つは役割が違います。

<!-- ページ全体のズームを禁止する(ページ単位の設定) -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
設定 効果 用途
user-scalable=no(viewport) ページ全体のユーザーズームを禁止 サイト全体でズームさせたくない時
touch-action: none(CSS) 指定要素のブラウザ標準ジェスチャを無効化し、イベントを要素に渡す canvasだけにタッチを渡したい時

user-scalable=no は、ページ全体のズームを禁止する設定です。canvas の上の2本指を canvas に渡すかどうかは、touch-action が決めます。ページ全体のズームを禁止すると、文字を拡大して読みたい人が困るという問題もあります。PoseMirror では viewport は initial-scale=1.0 のまま(ページのズームは許可)にして、canvas にだけ touch-action: none を指定しています。

原因詳細:ブラウザが2本指ジェスチャを横取りしている

不具合は次の手順で再現できます。

再現1:Unity 側にピンチの処理を書く

PoseMirror のカメラ操作(MouseLook.cs)のピンチ処理です。2本の指の間隔が変わった分だけ、カメラとモデルの距離を変えています。この処理自体に問題はありません。

void Update()
{
    // スマホ: 2本指ピンチでズーム
    if (Input.touchCount == 2)
    {
        Touch t0 = Input.GetTouch(0);
        Touch t1 = Input.GetTouch(1);

        Vector2 p0Prev = t0.position - t0.deltaPosition;
        Vector2 p1Prev = t1.position - t1.deltaPosition;
        float prevDist = (p0Prev - p1Prev).magnitude;
        float curDist  = (t0.position - t1.position).magnitude;

        float h = Mathf.Max(1f, Screen.height);
        // 指を広げる(curDist > prevDist)=ズームイン=カメラを近づける
        distance -= ((curDist - prevDist) / h) * pinchSpeed * distance;
        distance = Mathf.Clamp(distance, minDistance, maxDistance);
    }
}

再現2:touch-action を指定せずにスマホで開き、2本指ピンチをする

canvas に touch-action を指定しないまま公開し、スマホのブラウザで2本指ピンチをします。3Dモデルは拡大されず、ページ全体がズームします。1本指のスワイプ(回転)は動くので、C# のコードを疑いがちです。PC の Unity エディタではピンチを試せないので、スマホで開いて初めて気づきます。

なぜピンチが効かないのか

Unity の処理に問題はありません。Input.touchCount が 2 になっていないのが原因です。

スマホのブラウザは、2本指のタッチを、ページのピンチズームというブラウザ標準のジェスチャとして先に処理します。ブラウザがジェスチャを処理すると、ページ側へのタッチは途中で打ち切られます(MDN の touch-action の説明を参照)。Unity から見ると2本指のタッチが来ていない状態になり、ピンチの処理が動きません。

1本指でなぞる回転は動き、2本指だけが効かない。この症状が、ブラウザがジェスチャを横取りしているサインでした。

タッチがどこで消えているかを図にするとこうなります。

touch-actionなしでは2本指タッチをブラウザがページズームとして消費しcanvasに届かず、Input.touchCountは2にならない。touch-action:noneを指定するとブラウザは何もせずタッチがcanvasに届き、Input.touchCount==2が発火する

まとめ

Unity WebGL でピンチが効かないときは、Unity の C# より先に、ブラウザがジェスチャを横取りしていないかを疑います。#unity-canvas に touch-action: none; を1行足せば、2本指のタッチが Unity に届きます。viewport の user-scalable=no は役割が違う設定なので、ページのズームは許可したまま、canvas にだけ指定するのがおすすめです。

読み込むファイルを小さくする方法は、【Unity】Webアプリで表示するための軽量化方法にまとめています。この対応を入れたツールは、PoseMirror でスマホから触れます。

ピンチズームの効くWebGL、実物はこちら。

スマホで開いて、2本指ズームの挙動を確かめられます。

▶ ピンチズーム対応の3Dビューアを触る

参考資料

← Kabe-Tech トップへ