Posted at

UE4 マウスの位置をワールド座標に変換する

More than 3 years have passed since last update.


概要

表題のとおりです。

UE4で、マウスでクリックした場所に何かしたいときに役立つかもしれません。


デモ

マウスでなぞった空間上に連続した点を取り、それをつなぐようなメッシュを生成します。

そのあと再帰して枝が生えます(謎)

http://youtu.be/JqSXUpJrEoo


多分共通している部分


マウス入力を有効にする

UE4のデフォルトではマウス入力が無効となっています。

PlayerControllerでマウスに関する機能の設定ができます。

ランタイムでプロパティを書き換えることもできますが、

ここではPlayerControllerのクラスを置き換えることにします。

↓これを読んでください!

https://docs.unrealengine.com/latest/JPN/Resources/ContentExamples/MouseInterface/MouseControlSetup/index.html

なお、プロジェクトテンプレートによってはゲームモードは既に作成されており、PlayerControllerクラスを作成してそのゲームモードに割り当てるだけで済みます。


入力を受け取る

左ボタンのPress/Releaseを受け取るには

入力>マウスイベント>マウスの左ボタン

が使用できます。

mouseleft.PNG

マウスの座標をWorld座標系で得るには

Game>Player>ConvertMouseLocationToWorldSpace

が使用できます。

mousepos.PNG

これには二つの出力値

WorldLocation:(多分)カメラの座標

WorldDirection:カーソル方向のベクトル

があります。

マウスの座標には「奥行き」情報が無いため、

3次元のワールド座標に置き換えると一般的には「点」ではなく「半直線」になります。

ここからは、半直線から一つの点を特定するロジックについてです。


オブジェクトとの衝突を使用する方法

mouse_collision.PNG

レイトレースなどと呼ばれる呼ばれる手法で、ワールドに置かれた物体との衝突座標を取り出します。

これにはLineTraceByChannelが使えます。

● StartとEndの間に衝突可能な物体があれば

ReturnValue から true, OutHit から衝突情報が出力されます。

衝突しなければ

ReturnValue は false です。

● 入力値の "Start" には ConvertMouseLocationToWorldSpace からの WorldLocation がそのまま使え、"End" には WorldDirection * (適当な長さ) を入れるとよいでしょう。

● 出力値の OutHit は様々な情報を含んだ構造体になっており、衝突座標等を取り出したい場合は BreakHitResult を使います。


平面(Plane)との衝突を使用する方法

mouse_plane.PNG

本質的には似たようなものですが、物体ではなく数値で指定した平面との衝突座標を取り出します。

LinePlaneIntersection を用います。

入力にPlaneを受け取るところが先ほどと異なります。

このPlaneをどのように決めるかが鍵で、アプリケーションによって異なるところになりますが、

冒頭の動画では

* マウスのボタンが押され始めた時にコリジョンを用いて座標を得る

* その座標を通り、カメラの視線方向と垂直な平面を使用する

ようになっています。

以下のような感じでその平面を作れます。

makeplane.PNG

Planeに直接値を入れて生成しています。

Planeを作成のX,Y,Zに平面の法線ベクトルを、

Wに平面上の点を法線軸に射影(dot product)したものを入れます。

グラフ上部からドット積ノードにつながっているのはコリジョンを使って作った座標です。


まとめ

表題の件について、実現方法の紹介をしました。

以上です。