［UE5］ウィジェット上のマウスカーソルの座標を取得する

# 概要
この記事ではUnreal Engine 5で、下記のそれぞれの条件下で、ウィジェット上のマウスカーソルの座標を適切に取得する方法をお話しします。

1. ウィジェットとウィンドウ画面のアスペクト比が同じとき
1. ウィジェットとウィンドウ画面のアスペクト比が異なるとき
1. ゲームプレイ画面が小さいとき


# この記事の主な対象者
- Widget Blueprint（WBP）の作り方の基礎を習得されている、初心者の方


# 前提知識
この記事における「ウィジェット上の座標」というのは、WBPのエディタの座標のことを指します。

例として、ウィンドウ画面でマウスカーソルが下図の位置（ウィジェット部分の中心）にある場合を考えます。

![mousepos_exp1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/d086e9e2-f91b-fb39-d6c7-54d635c2eb45.jpeg)
（上図は、下の記事で作成した、アスペクト比が一定になるウィジェットを表示したときのウィンドウ画面です。）

https://qiita.com/tuduru/items/1745f5f5df782164e6f7

<br>
上図の場合における「ウィジェットの座標」というのは、下図のように、ウィジェットブループリントにおける中心の座標のことを指します。（下図だと、赤枠で囲ったサイズを2で割った、緑色の文字の座標となります。）

![mousepos_exp2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/09e540e3-56a5-6575-0f16-8a59aed42d3e.jpeg)






# 1. ウィジェットとウィンドウ画面のアスペクト比が同じとき

ウィンドウ画面上のマウスカーソルが、画面に表示しているウィジェット上のどこにあるかを取得するには、下図の「Get Mouse Position on Viewport」ノードを使用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/2c36d2aa-a077-204f-3baf-01416db57557.png)<br><br>

下の動画のように、「Get Mouse Position on Viewport」ノードから取得した値をメッセージとして画面左上に表示してみると、適切な値が取得できていることがわかります。
（この記事で用いているウィジェットのサイズは、1922 × 1081 ですので、ウィンドウ画面左上端の座標が (0, 0)、右下端の座標が (1922, 1081) となっていれば、正常にウィジェット上におけるマウスカーソルの位置を取得できているとわかります。）

<iframe width="640" height="360" src="https://www.youtube.com/embed/TYIkVdcAsx0" title="mousecursorpos 1 1" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>


# 2. ウィジェットとウィンドウ画面のアスペクト比が異なるとき

この記事では下の動画のように、アスペクト比が一定になるウィジェットを画面の中央に表示していて、ウィジェット上の座標を正しく取得できない場合の対処方法をお話しします。

<iframe width="640" height="360" src="https://www.youtube.com/embed/9SeQTHdcheY" title="mousecursorpos 1 2" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
<br><br>

上の動画を見ていただくと、下図の赤点の座標が(0, 0)となっていないのがわかると思います。その原因は、ウィジェットのアスペクト比を保つことで、**ウィンドウ画面に余白が生まれてしまうから**です。

![greenpoint.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/9e3e06e5-698b-2f59-c371-5d9f1737bd16.jpeg)<br><br>

解決方法をお話していくにあたって最初に、ウィジェットとウィンドウのアスペクト比が異なり、画面に余白が生まれるとき、取得できる座標の範囲がどのようになるかをご説明いたします。

![coordinate_exp1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/e4abf5d2-40f4-aeed-857d-14657baf6c33.jpeg)

説明で使用する例では、ウィジェットのサイズは 1920 × 1080 とします。

上図のように余白が生まれたとき、ウィンドウ上で取得できる座標の範囲の大きさは、（緑線の長さ + 赤線の長さ）となります。つまり、上図の縦軸においては、余白が発生していないため、ウィジェットサイズである1080が取得できる座標の範囲の大きさとなり、横軸においては、（ 1920 + 余白サイズ ）が取得できる座標の範囲の大きさとなります。

余白が生まれてもウィンドウの左上端（上図の赤点）の座標が（0, 0）となるので、ウィジェットの左上端（緑点）の座標を（0, 0）としてマウスカーソルの位置を取得したい場合は、「Get Mouse Position on Viewport」ノードから取得した値から、（追加された余白のサイズ ÷ 2）の分だけ引く必要があります。<br><br>

それでは、実際に下図のように「Get Mouse Position on Viewport」ノードから取得した値から、（追加された余白のサイズ ÷ 2）の分だけ引く処理のノードを組んでいきます。

今回の記事では、アスペクト比が一定となるウィジェットは、私が過去に書いた下の記事のウィジェットを用います。そのため、アスペクト比が一定となるウィジェットの構成は、下図のようになっているとします。

https://qiita.com/tuduru/items/1745f5f5df782164e6f7

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/d9c91b52-110b-116c-8780-50b1beeebe91.png)
（「Canvas Panel」ウィジェットの「TestWidgetCanvas」の下にあるウィジェットが、一定のアスペクト比を保つようになっています。）<br><br>


最初に、「TestWidgetCanvas」ウィジェットを選択し、詳細パネルの「Is Variable」にチェックを入れ、変数として扱えるようにします。後で、ウィジェットの縦横サイズを取得するのに使用します。

![isvarialbe.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/b32a91ca-00ca-e07a-6c34-2b92ceffaa63.jpeg)<br><br>

次に、マウスカーソルの座標を求める処理を記述したいイベントグラフを開き、下のノードを組みます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/6c6679b2-96b8-b73a-f0c4-e651380cd50e.png)
（「Test Widget」は上で「TestWidgetCanvas」を変数として扱えるようにした、アスペクト比が一定となるウィジェットの変数です。）

求めた座標をウィンドウ左上にメッセージとして表示するようにして、余白が生まれているときも、マウスカーソルの座標がウィジェット上の座標を適切に取得できているかどうかを確認します。
（この記事で用いているウィジェットのサイズは、1922 × 1081 ですので、ウィジェット左上端の座標が (0, 0)、ウィジェット右下端の座標が (1922, 1081) となっていれば、正常にウィジェット上におけるマウスカーソルの位置を取得できているとわかります。）

<iframe width="640" height="360" src="https://www.youtube.com/embed/w-nRhSnFrRs" title="mouseposcursor 1 3" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>


# 3. ウィンドウ画面が小さいとき

サイズが 1920 × 1080 であるウィジェットを、画面サイズが 640 × 360 のウィンドウ（アスペクト比は 16 : 9）に表示している状態で、「Get Mouse Position on Viewport」ノードを使用してみると、ウィンドウの右下端の座標が、(1920, 1080)よりも小さくなっていると思います。

これは、**Unreal Engineが管理しているDPIスケールの値が、デフォルトだと一定以下の値にはならないようになっているから**です。

「Get Mouse Position on Viewport」でマウスカーソルの座標を取得する処理の中にも、DPIスケールの値が利用されているため、正常なDPIスケールの値を取得できる状態にないと、正しいマウスカーソルの座標を取得することができません。

なのでこれから、正常なDPIスケールの値を取得できるようにしていきます。<br><br>

DPIスケールの値が正常な値になるようにするために、「プロジェクト設定」＞「DPIスケーリング」＞「DPIカーブ」を開きます。

「プロジェクト設定」＞「DPIスケーリング」＞「DPIカーブ」のグラフの、一番左端の点をクリックしてみると、下図の赤線のように「Scale」の値が表示されます。

![dpiscale1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/e98f035a-de31-ee8c-fde7-b302c4db3e4e.jpeg)

上図では、一番左の点の「Scale」の値が 0.444 となっており、その点の左側の線が左下に下がっているのではなく、横に線が引かれている状態にあることから、DPIスケールの値が 0.444 未満になることがない状態になってしまっていることがわかります。<br><br>

0.444 未満の値にもなるようにするために、「プロジェクト設定」＞「DPIスケーリング」＞「DPIカーブ」のグラフの、一番左端の点をクリックし、赤線の「Resolution」「Scale」の値を0に設定します。

![dpiscale2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/1228b8ba-5e07-270b-bdb7-217577007e2a.jpeg)

これで、DPIスケールの値が 0.444 未満の値になるようになり、ウィンドウ画面が小さくても「Get Mouse Poistion on Viewport」ノードで、正しいマウスカーソルの座標を取得できるようになります。
<br><br><br>



以上で今回の記事の内容は終了です。
最後まで読んでいただき、ありがとうございました。