・・・お久しぶりです。どうしても書きたいネタがあるわけでもないので困っている男ミデンです。
えー 前回の投稿から若干間が空いてしまいましたが、いかがお過ごしだったでしょうか?
わたくしも決してサボりたくてサボっていたわけではありません!断じて!
サボりたくはなかったのでありますが、結果としてサボっていたのは誠に遺憾であります。
あ、はい、理由ですか?
記憶にございません!!
さて、いつもの前置きはこのくらいに、さっそく内容に入っていきたいと思います(強引)
今回は「クリック・ドラッグ・ダブルクリックで操作する3Dビューアーを作ろう」ということで、
要するに
マウス操作でグリグリできる3Dビューアーが作りたいよぉ~
ということです。
それでは早速
まずはProjectの作成からFirstPersonを用意して、First PersonCharactorの移動モードをFlyingしたら、はい完成!終わりー!
とすると身も蓋もないので、文字数のある記事にするためにもブループリントを使って1から実装していきたいと思います。(ここも尺稼ぎ)
ちなみにタイトル画像ですが、なんでも最近は擬人化した馬人間を走らせるゲームが流行りだということでそれにあやかってみました。
【3Dビューアー全体構成】
3Dビューアーでよくある基本的な操作・機能を以下のように実装します。
・右ドラッグ:前後移動(画面に対して前後に移動)
・左ドラッグ:回転移動(アクターの位置を中心軸にして回転移動)
・両ドラッグ:平行移動(画面に対して平行に移動)
・左ダブルクリック:カーソル指定位置への移動
・右ダブルクリック:画面解像度の変更
・ホイール:ズーム
・ホイールボタン:パース投影・並行投影のモード変更
使用するアセットはこちら
・Pawnクラスのブループリント
・列挙型
それではアセットを準備していきます。
Pawnを親にしたブループリントを作成しレベルに配置します。
ブループリントエディタを開いてコンポーネントを追加していきます。
まずDefaultSceneRootの下にSceneComponentを子付けし、名前をScene_Rotationと付けます。
更にその下にSceneComponentを子付けし、今度は名前をScene_Locationとします。
そしてScene_LocationにCamera Component(カメラ)を子付けして、
Z軸の回転値を-90.0、Y軸座標位置をNear Clip Planeのデフォルト値である10.0と設定します。
Scene_Locationを動かすことで前後移動と平行移動を行い、Scene_Rotationを回転移動時の回転軸になります。
コンポーネントの準備が終わったらStart with Tick Enabledのチェックを外し、Auto Possess PlayerをPlayer 0にします。
続いて列挙型を作成して、上から「None」「前後移動」「回転移動」「平行移動」の順に表示名を入れます。
それではブループリントの作業に移ります。
【カーソルの表示】
Begin PlayイベントではPlayer ControllerのShow Mouse Cursorにチェックを入れてマウスカーソルの表示を行います。(上の画像を参照)
【入力イベント】
使用するマウスとキーボードの入力イベントです。
・Right Mouse Button
・Left Mouse Button
・Mouse Wheel Up
・Mouse Wheel Down
・Middle Mouse Button
・Escape
マウスボタンの入力イベントには、上記以外にThumb Mouse Button、Thumb Mouse Button 2があり、デフォルトでは5ボタンのマウスまで対応しているようです。
9ボタンマウスで確認したところ、6から上はAny Keyイベントの反応はありませんでした。
また、ダブルクリックですが、調べた限りブループリントには専用のイベントはないようです。
(ウィジェットブループリントにはOnMouseButtonDoubleClickという関数が用意されています)
EscapeキーイベントはQuit Gameに繋いでアプリケーションを終了できるようにしておきます。
【Key構造体から情報を取得】
クリックイベントの処理をブループリントで作成していきます。
必要な情報はキー構造体から取得できるのでクリックイベントの引数はこれだけになります。
Key構造体でマウスボタンの左右を判別し、Was Input Key Just Pressedからボタンの状態を取得して変数に格納します。
その後、反対のボタンの状態によって、それぞれに対応したマウスドラッグ用のイベントを実行します。
ダブルクリックも取得したいので、そちらのイベント作成します。
引数はクリック用イベント同様にキー構造体です。
マウスボタンを判別するためのキー構造体変数と、クリック回数を調べるためのInt型変数を用意します。
クリック間隔の判定するRetriggerableDelayには、とりあえず0.3を設定しておきます。
マウスボタンを押した時に直前のマウスボタンと同じでカウンターが2以上であればカウンターを0にしてダブルクリック用のイベントが走ります。
このイベントはクリックイベントの直後に配置します。
【Get Mouse Position on Viewportでマウスの移動量を取得】
マウスドラッグで行う移動操作用のイベントを作成します。
イベントの引数には移動タイプを判別するために作成したEnumを使用しています。
(Enumは上からNone、前後移動、回転移動、平行移動)
はじめに移動タイプを変数に格納します。
それからScene_Locationの位置にアクターを動かして相対位置を0にリセットします。
続いて移動タイプごとに前処理を行います。
<前処理>
・前後移動
Get Mouse Position on Viewportを使って画面上のマウスの現在座標を取得しVector2Dの変数StartPositionに格納します。
・回転移動
現在のX軸とZ軸の回転値をVector2Dの変数StartRotationに格納し、その後は前後移動と同様です。
・平行移動
前後移動と同じなのでそちらに繫ぎます。
<移動処理>
続いて移動処理です。移動処理はTickイベントで行います。
移動タイプによって違いますので、まずは前後移動から。
・前後移動
Get Mouse Position on ViewportからStartPositionを引いた差分(マウスの移動量)のY成分に係数をかけてScene_Locationの相対座標のY軸成分にします。
係数はここでは5としておきます。
マウスを上下に動かすとカメラが前後に移動します。
・回転移動
次に回転移動です。
同じくマウスの移動量を(x)2,(Y)-2で割ったX成分をStartRotationのY成分と足してScene_Rotationのワールド回転のYawに、
Y成分をStartRotationのX成分と足してScene_Rotationのワールド回転のRollにします。
・平行移動
最後に平行移動です。
マウスの移動量に今度は(X)-5,(Y)5をかけてX成分をScene_Locationの相対位置のX軸成分に、Y成分をZ軸成分にします。
基本的な移動処理は以上です。
続いてズームなどその他の機能を作っていきます。
【Set Field Over Viewでズーム】
カメラの画角をSet Field Over Viewで変更してズーム機能を実装します。
CameraのField Of Viewの値を取得します。
その値にマウスホイールの回転方向によって加算または減算を行い、数値が10.0からデフォルト値の90.0の間になるようにClampしてSet Field Over Viewに繋げます。
【Set Projection Modeで投影モードを変更】
CameraのProjectionModeがパースペクティブモードであれば平行投影モードに、なければパースペクティブモードにSet Projection Modeを使ってスイッチさせます。
平行投影モードにした時パースペクティブモードとの見た目の差が大きくなりすぎないようにCameraのField Of Viewと中心からの距離を元に適当に調整しています。
【Get Hit Result Under Cursor でマウス直下のオブジェクト情報を取得】
カメラの位置をマウスで指定したオブジェクト表面上の位置に変更します。
Get Hit Result Under Cursor for Objects(またはGet Hit Result Under Cursor for Channel)を使ってカーソル直下にレイを飛ばしてコリジョンのヒットを調べます。
ヒットしたらHit ResultのLocationから座標を取得してSet Actor Locationで移動します。
【画面解像度の変更】
はじめにGet Supported Fullscreen Resolutionsでモニターでサポートされているフルスクリーン解像度を取得します。
解像度の配列は小さいサイズから入っているので、ここでは大きいサイズから段々小さくなるように最後尾からサイズを取得します。
Get Game User Settingsでユーザー設定を取得したらSet Screen Resolutionで解像度を指定、フルスクリーンモードはwindowedに変えておきます。
最後にApply Settingsで変更を反映させます。
以上ですべての機能の実装が終わりました。
ブループリント全体図
今回はこれで終わりとなります。
お付き合いいただきありがとうございました。
ここまで作ってみての感想ですが、やはりCharactorを親クラスに使ったほうがシンプルでいいですね!(ぉぃ)
しかしですね、こういうふうにテーマを決めて制作していると、その過程でいろいろな発見があったりでとても勉強になるわけですね。
と、そんなこんなでせっかくなので次回はこれにハムスターの回し車を入れてマウスでハムハムが楽しめるようにできたらいいなぁと画策中(やった!これで次回はネタに困らないぞ!)
それではまた次回のブログでお会いしましょう!じゃん・けん・ぽん☆
例によって自己責任でお願いしますm(。。)mペコリ