※UE4のバージョンは4.26.2を使用しました
こんにちは。
情熱開発部・プログラム課の日高です。
今回はUE4で取得出来るカーソルの座標系と、座標系の変換方法を紹介します。
UE4ではカーソルやウィジェットの計算をするときに、座標系の変換をすることがあるのですが、カーソル位置は取得方法によって座標系が異なります。
変換に使う関数もいくつかあるので、どうすれば目的の座標系までもっていくことができるのか分からなくなることが何度もありました。
なので、座標の変換で迷うことがなくなるように座標系と変換方法についてまとめてみました。
座標系について
最初に、今回使用する以下4つの座標系について説明します。
- 1)スクリーン座標
- 2)クライアント座標
- 3)ウィジェットのローカル座標
- 4)ビューポート座標
![](https://i0.wp.com/logicalbeat.jp/wp01/wp-content/uploads/2021/07/0000_Screen_Client-1.jpg?fit=640%2C360&ssl=1)
1)スクリーン座標
ディスプレイの左上を原点とした座標。
UE4では「Absolute」「Platform」「Screen Space」等と記載されています。
2)クライアント座標
枠を除いたウィンドウの左上を原点とした座標です。
3)ウィジェットのローカル座標
![](https://i0.wp.com/logicalbeat.jp/wp01/wp-content/uploads/2021/07/0003_Widget-1.jpg?resize=640%2C360&ssl=1)
ウィジェットの左上を原点とした座標系で、ボタンやキャンバスパネル等、すべてのウィジェットに存在しています。
4)ビューポート座標
![](https://i0.wp.com/logicalbeat.jp/wp01/wp-content/uploads/2021/07/0002_Client-1.jpg?resize=640%2C360&ssl=1)
「2)クライアント座標 」と範囲は同じですが、DPIScaleで割った座標系です。 (今回はDPIScaleに関しての説明は省きます。)
左上では共に(0, 0)になりますが、右下に行くにつれ差が広がります。
「2)クライアント座標」と「4)ビューポート座標」でのカーソル位置を表示して違いを確認してみました。
![](https://i0.wp.com/logicalbeat.jp/wp01/wp-content/uploads/2021/07/0305_Viewport-2.gif?resize=386%2C259&ssl=1)
また、画面左上を原点にして設置したウィジェットもこの座標系になります。
座標系を変換する方法
4)ビューポート座標 へ変換する
確認用に全画面に表示されるキャンバスパネル(原点が画面左上なのでビューポートと同じ座標系になる)の左上にUE4のロゴを置き、ロゴがカーソルに追従するウィジェットを作成しました。
![](https://i1.wp.com/logicalbeat.jp/wp01/wp-content/uploads/2021/07/0300_WidgetBP-3.jpg?fit=640%2C296&ssl=1)
1)スクリーン座標 → 4)ビューポート座標
スクリーン座標からの変換では、ビューポートウィジェットのジオメトリでAbsoluteToLocal関数を通します。
![](https://i1.wp.com/logicalbeat.jp/wp01/wp-content/uploads/2021/07/image-9.png?fit=640%2C100&ssl=1)
AbsoluteToViewportでも変換できます。
![](https://i0.wp.com/logicalbeat.jp/wp01/wp-content/uploads/2021/07/image-8.png?resize=640%2C127&ssl=1)
2)クライアント座標 → 4)ビューポート座標
クライアント座標から変換する場合は、ViewportScaleで割るだけでOKです。
![](https://i1.wp.com/logicalbeat.jp/wp01/wp-content/uploads/2021/07/image-10.png?fit=640%2C176&ssl=1)
変換が成功すると以下の用にロゴがカーソルに追従するようになります。
![](https://i2.wp.com/logicalbeat.jp/wp01/wp-content/uploads/2021/07/0306_Viewport-2.gif?fit=640%2C378&ssl=1)
3)ウィジェットのローカル座標へ変換する
確認用に画面中央にキャンバスパネル(LogoCanvas)を置き、その左上に設置したUE4のロゴがカーソルに追従するウィジェットを作成しました。
![](https://i1.wp.com/logicalbeat.jp/wp01/wp-content/uploads/2021/07/0301_WidgetBP-2.jpg?fit=640%2C305&ssl=1)
1)スクリーン座標 → 3)ウィジェットのローカル座標
スクリーン座標からの変換では、 変換先のウィジェット(LogoCanvas)のジオメトリでAbsoluteToLocalを行います。
![](https://i1.wp.com/logicalbeat.jp/wp01/wp-content/uploads/2021/07/0203_ScreenToWidet.jpg?fit=640%2C166&ssl=1)
2)クライアント座標 → 3)ウィジェットのローカル座標
クライアント座標からの変換では、 スクリーン座標を経由する必要があるため、以下の手順で変換します。
- ViewportScaleで割ってビューポート座標へ変換する
- ビューポートのジオメトリでLocalToAbsoluteを行い、スクリーン座標に変換する
- 変換先のウィジェット(LogoCanvas)のジオメトリでAbsoluteToLocalを行い、ウィジェットの ローカル座標へ変換する
![](https://i1.wp.com/logicalbeat.jp/wp01/wp-content/uploads/2021/07/0204_ViewportToWidet.jpg?fit=640%2C159&ssl=1)
4)ビューポート座標 → 3)ウィジェットのローカル座標
ビューポート 座標からの変換では、スクリーン座標を経由する必要があるため、以下の手順で変換します。
- ビューポートウィジェットのジオメトリでLocalToAbsoluteを行い、スクリーン座標に変換。
- 変換先のウィジェットのジオメトリでAbsoluteToLocalを行い、ウィジェットの ローカル座標へ変換
![](https://i0.wp.com/logicalbeat.jp/wp01/wp-content/uploads/2021/07/0205_ClientToWidet.jpg?fit=640%2C156&ssl=1)
カーソル位置の取得方法とその座標系の紹介
カーソル位置 or タッチ操作の取得方法とその座標系をいくつか紹介します。
1)スクリーン座標が取れる関数
- GetMousePositionOnPlatform
![](https://i0.wp.com/logicalbeat.jp/wp01/wp-content/uploads/2021/07/image-1.png?resize=225%2C77&ssl=1)
- MouseEventのGetScreenSpacePosition
![](https://i0.wp.com/logicalbeat.jp/wp01/wp-content/uploads/2021/07/image-2.png?resize=300%2C91&ssl=1)
2)クライアント座標が取れる関数
- PlayerControllerのGetMousePosition
![](https://i0.wp.com/logicalbeat.jp/wp01/wp-content/uploads/2021/07/0403_GetMousePosition.jpg?resize=300%2C87&ssl=1)
- InputTouchのLocation
![](https://i0.wp.com/logicalbeat.jp/wp01/wp-content/uploads/2021/07/image-4.png?resize=145%2C179&ssl=1)
4)ビューポート座標が取れる関数
- GetMousePositionOnViewport
![](https://i0.wp.com/logicalbeat.jp/wp01/wp-content/uploads/2021/07/image-5.png?resize=225%2C83&ssl=1)
最後に
変換は関数を1つ、2つ通すだけでできてしまうので簡単ですね。
座標系が把握できれば変換で戸惑うこともなくなりそうです。
取得した値がどの座標系か分からない時は、GetMousePositionOnViewport等座標系が分かっている物と比較すると分かり易いと思います。
それでは。最後までご清覧頂きありがとうございました。
【免責事項】
本サイトでの情報を利用することによる損害等に対し、
株式会社ロジカルビートは一切の責任を負いません。