ゲーム開発の備忘録

趣味のゲーム開発でのノウハウや、技術的に嵌ったポイントを忘れないように書き記しておくブログです。

libGDXでモバイルアプリ開発時にタッチ位置が画面内位置とずれる場合の対処法

はじめに

libGDXでモバイル端末向けゲームを開発時にチュートリアルや入門記事通りに進めると嵌る可能性が高いのが、画面内のボタンをタッチして押そうとしてもタッチ位置がずれるため、正常に判定ができないという問題です。
私も開発中期の頃に嵌ったのですが、なかなか記事にする時間がとれませんでした。忘れないうちに記事として残しておこうと思います。

対処法

カメラのunproject()時に、ビューポートの情報を渡しましょう。

タッチ位置は2D空間のスクリーン座標で取得されるため、Camera系統のクラスのunproject()を利用して、射影変換の逆変換を行い3D空間の座標にする必要があります。
上記の方法自体は入門記事やチュートリアルでも確認できますが、このままだとディスプレイによってはタッチ位置がずれてしまいます。
そこで、第5引数まであるオーバーロードされたunproject()を利用します。利用方法は以下のような感じ。(Kotlinで書いてます)

camera.unproject(touchPos, viewport.screenX.toFloat(), viewport.screenY.toFloat(), viewport.screenWidth.toFloat(), viewport.screenHeight.toFloat())

この方法だと、ビューポートの情報を参照して適切な補正を掛けてくれるようになり、タッチ位置がずれなくなります。
JavaDocとにらめっこしている時に何とか見つけました。

余談

libGDXでシェーダを利用するときは、Meshクラスを用いてポリゴンを作成する必要があります。
フルスクリーンのポリゴンを作成する場合にも、ビューポートの情報が役立ちます。
Gdx.graphics.width, Gdx.graphics.heightでポリゴンを作成するとディスプレイによってはずれることがあるので、

Gdx.graphics.height * (Gdx.graphics.height / viewport.screenHeight)

のようにサイズを補正してあげることで、ずれがなくなります。