Tobii EyeX が届いたので見つめ合ってみた
届きました。
CEDECに行ったら50名限定で無料で貰えるということだったので、せっかくだからと貰ってきました。
Tobii EyeX とは
視線入力デバイスです。
PCの前に座っている人が画面のどこを見ているのかを検知することが出来ます。
これは体験しないとわからないことですが、意外とトラッキングの精度は良いです。
C++用のSDKに加えて、UE4やUnityで使用するためのプラグインも公開されています。
さっそく動かす
届いたのですぐさま開封。
開発者登録も済ませ、新参UE4勢なのでUE4のプラグインを見に行ってみたら…
おおお、TobiiのUE4対応バージョンって4.6かよ
— ほげたつ (@HogeTatu) 2015, 9月 1
( ゚д゚)…
最新は4.9だというのに…。
とりあえず4.9にコンバートしてみたら案の定ビルドエラーにw
仕方ないのでリポジトリをフォークしてちまちま対応しました。
Tobii EyeX をUE4バージョン4.9に対応させました。導入手順等は本家と同じです。@TobiiEyeX
https://t.co/rmJpmX34vO
— ほげたつ (@HogeTatu) 2015, 9月 1
これで動くと思います。
見つめ合ってみた
目と目が合う〜 #UE4 #TobiiEyeX pic.twitter.com/bq4yvlu9YT
— ほげたつ (@HogeTatu) 2015, 9月 4
ぶっちゃけこれがやりたかっただけです。
UE4マネキンちゃんきゃわわ(棒
UE4でBlueprint上からHTTP通信を行うWebApiプラグインを公開しました
2015/10/22 追記 --------
ver.2.0 を公開しました。
追記ここまで --------
HTTP通信を調べていて、JsonFieldDataの中身を見て、これくらい揃っているならアレとコレがあればもっと使いやすくなるなーと思ってエンジン内を見始めたら既にほぼ揃っていたw
— ほげたつ (@HogeTatu) August 8, 2015
あとは通信処理課程でリクエストやレスポンスに対してPreFilterとPostFilterだけ掛けられたら文句無しっぽいのでそれはやろうかな
— ほげたつ (@HogeTatu) August 8, 2015
あ、JsonFieldDataはJSONQueryプラグインに入ってるものです。https://t.co/gCi0nx9PCc https://t.co/vSG5pKekd3
— ほげたつ (@HogeTatu) August 8, 2015
作りました。
詳細は日本語READMEを読んで下さい。
https://github.com/HogeTatu/UE4Plugin_WebApi/blob/master/README.jp.md
日本語版の各機能サンプルREADMEを見てもらえれば、なんとなく使い方を想像できるかと思います。
- シンプルなGET通信サンプル https://github.com/HogeTatu/UE4Plugin_WebApi/blob/master/Examples/01_SimpleGet/README.jp.md
- シンプルなPOST通信サンプル https://github.com/HogeTatu/UE4Plugin_WebApi/blob/master/Examples/02_SimplePost/README.jp.md
- JSONフォーマットでレスポンスを受け取った時に中身をパースするサンプル https://github.com/HogeTatu/UE4Plugin_WebApi/blob/master/Examples/03_JsonResponse/README.jp.md
こんな感じで使えます。
利用に関して
【追記】ライセンスに関して一部修正しました
一応これまでの経験を元に商用プロジェクトでも使えるような作りを目指して作っていますが、初めてのプラグイン作成 and 短期間で作ったものなので作りが荒かったりバグがあったりするかもしれません。
ライセンスはMITなので、商用・非商用問わずに好きに使って構いません。
あと英語READMEは拙い英語なので、もし文法的に間違っている点があったら教えてもらえると助かります。。
UE4でレーザービームを実装する
アイアンマンとか見ててレーザーを打ちたくなったので。障害物による中断と打ち終わった後に急に消えないようにする対応で少し複雑になってしまった。ブログは後でパーティクル作成と発射処理を分けて書くつもり。 #UE4Study pic.twitter.com/C3l6jCKjg5
— ほげたつ (@HogeTatu) 2015, 7月 27
これの実装手順です。
パーティクル作成と発射処理を分けて書こうと思っていた時期もありましたが、パーティクル編がほぼチュートリアルと同じなので割愛することにしました。
パーティクル作成まで
パーティクル用のマテリアルをBeamMaterial、パーティクルをBeamParticleという名前で作成します。
この辺りは上記チュートリアル動画の6:14くらいまでとほぼ同様なので、そちらを見ながら作成して下さい。
チュートリアル動画から、ParticleEmitterに以下の変更を加えています。
- Lifetimeを0.1に変更
- InitialColorを(20, 5, 0)に変更
- SourceのSourceMethodをUserSetに変更
- TargetのTargetMethodをUserSetに変更
LifetimeやSourceMethod、TargetMethodはBP側からパーティクルの位置や消失を制御するための変更です。
銃のモデルをShooterGameデモから持ってくる
[UE4] 他プロジェクトからアセットを移動させる方法 | historia Inc - 株式会社ヒストリア
この辺りを参考にWeapons/Rifleをコピーしてきます。
ライフルでビーム?とか細かいことは無しで…
腕のメッシュに銃アタッチ用のソケットを追加
hand_rにRightHandという名前でソケットを追加します。
プレビューで見ながら、LocationとRotationをいい感じにします。
銃のBPを作成する
FirstPersonGunという名前でBPを作成し、
- DefaultSceneRoot
- SkeletalMesh(SkeletalMesh)
- BeamParticle(ParticleSystem)
- BeamHitParticle(ParticleSystem)
- BeamParticle(ParticleSystem)
- SkeletalMesh(SkeletalMesh)
という階層でコンポーネントを追加します。
SkeletalMesh
- スケルタルメッシュにRifleを設定
BeamParticle
レーザービーム本体のパーティクルです。
- ParticlesのTemplateにBeamParticleを設定
- AutoActivateのチェックを外す
BeamHitParticle
レーザービームが障害物に当たった時の火花パーティクルです。
- ParticlesのTemplateにP_Sparksを設定
- AutoActivateのチェックを外す
※P_Sparksは元が青っぽいパーティクルだったので、色をオレンジっぽく変えてあります。
実行時にプレイヤーが銃を持つように設定する
FirstPersonCharacterのBPを開き、イベントグラフに以下の処理を追加します。
BeginPlay時に、FirstPersonGunをスポーンし、後から使うためにGunという変数にリファレンスを保持しています。
その後、AttachToを使ってRightHandのソケットに対してアタッチしています。
ここで試しに実行してみて、正常に銃がアタッチされていることを確認します。
レーザービーム発射処理の流れ
- ビームは照射直後、時間経過により長さが伸びていく
- ビームの長さには制限がある
- ビーム停止後はビーム開始点から時間経過により長さが短くなっていく
- ビームの長さがほぼ0になったら非アクティブ化する
必要な変数宣言
FirstPersonGunに必要な変数を宣言します。
- EmitTimer(float)
ビーム照射時間
- EmitStopTime(float)
ビーム照射停止時間
- BeamLenMax(float)
ビームの長さの最大値
動画では5000
- BeamSpeed(float)
ビームの速さ
動画では10000
- EmitStartDistance(float)
発射口からのビームパーティクル開始位置
- EmitEndDistance(float)
発射口からのビームパーティクル終了位置
- EmitStop(bool)
ビーム照射停止フラグ
照射開始する関数定義
Emit
照射後のビーム更新処理全体図
ここが一番複雑ですが、ひとまず全体の流れです。
細かく分割しながら見ていきます。
ビーム有効判定と照射時間更新
Emit関数内でBeamParticleをActive化しているので、それを見て更新処理を実行しています。
更新処理の頭では照射開始からの継続時間(照射時間)を更新しています。
ビーム長の更新処理と非アクティブ化判定
ビーム照射中は照射停止判定とビームパーティクル終了位置の更新を行います。
ビーム照射停止後はビームパーティクル開始/終了位置どちらも更新が必要です。
また、前述している通り、ビームの長さがほぼ0になる(開始位置が終了位置に追いつく)と非アクティブ化して終了を待ちます。
※パーティクルを非有効化したら放出は止まりますが、すぐには完全に非アクティブになりません。
放出中のものが消えるまで、IsActiveの判定はtrueのままになるので注意が必要です。
ビームパーティクル位置の計算と障害物当たり判定
変数上ではビームパーティクルの位置を長さで持っていますが、ここで実際にどの位置なのかの計算を行います。
GetWorldRotationからGetForwardVectorすることでパーティクルの向きが単位ベクトルとして取得できるので、それに長さを掛けたものにGetWorldLocationで取得したパーティクルの原点(発射口)を足してあげることで位置が計算できます。
障害物の当たり判定にはLineTraceByChannelを使用しています。
これはStartとEndの間を直線で辿った時に、ヒットしたものを取得できるものです。
今回の当たり判定では目で見えるものに当たり判定を行いたかったので、TraceChannelはVisibilityで設定してあります。
当たり判定後の処理
SetBeamSourcePoint/SetBeamTargetPointはビームパーティクルの開始/終了位置を設定できるものです。
つまりLineTraceした時に、当たり判定開始地点はビームパーティクルの開始地点、実際に当たった地点がビームパーティクルの終了地点という事になります。
当たりが発生した場合、終了位置の更新の他、ビームヒット用パーティクルの有効化、終了位置用の変数を当たった地点に合わせて更新するといった処理を行っています。
当たりが発生しなかった場合は終了位置を当たり判定終了地点に設定するのみです。
Emit関数を呼ぶ
最後にFirstPersonCharacterを開き、照射開始のイベントを追加します。
イベントグラフの中に既にSpawn projectileという処理があり、ここの内容を今回作成したものに置き換えるだけです。
これで実装完了です
UE4でゲームデータのセーブ/ロード
多くのゲームではデータのセーブ/ロードを実装します。
今回はUE4でローカルファイルへのセーブ/ロードを試してみました。
UE4のバージョンは4.8.2です。
プロジェクト作成
ThirdPersonテンプレートを使用してプロジェクト作成。
キー登録
「編集」→「プロジェクト設定」→「インプット」→「Action Mappings」にキー登録。
- Load Game
- 0キー
- Save Game
- Shift + 0キー
セーブデータクラスを作成
SaveGameを継承してセーブ用のBlueprintを作成します。
保存する内容をセーブデータクラスに記述
今回はプレイヤーの位置情報を保存するので、Transform型で「PlayerTransform」という変数を定義します。
ロード用の関数定義
レベルのブループリントを開き、LoadGameDataという関数を実装します。
GameDataというのはセーブデータクラスをメンバとして宣言したものです。
ロード時はまずGameDataがNullかどうかチェックし、もしNullであれば新規で作成しています。
その後、「Load Game from Slot」でファイル保存されているセーブデータをロードし、プレイヤーの位置情報を上書いています。
セーブデータにはスロット名とユーザーインデックスが指定できます。
スロット名はセーブデータの名前、ユーザーインデックスはその中でのIDみたいなものですね。
ドラクエの冒険の書1とか冒険の書2とかそんなイメージです。
セーブ用の関数定義
レベルのブループリントを開き、SaveGameDataという関数を実装します。
セーブ関数が呼ばれたら、プレイヤーの位置情報を取得してGameDataのPlayerTransformを更新し、「Save Game to Slot」でファイル保存しています。
呼び出し処理
レベルのブループリントのイベントグラフを開き、セーブ/ロード用の関数呼び出しを実装します。
こんな感じになりました
UE4でゲームデータをセーブ/ロード。位置をセーブしていて、ロードしたらセーブした位置に戻る。 pic.twitter.com/r9lCpyQRza
— ほげたつ (@HogeTatu) 2015, 7月 25
UE4でカメラズーム
8月からUE4を使う会社で働きます。
なので練習がてらUE4でカメラのズーム機能を実装してみました。
UE4のバージョンは4.8.2です。
【追記】カメラを2つ用意する方法だと近くのオブジェクトが見えなくなる問題があったため、FOVを使う形に記事を修正しました。
プロジェクト作成
FirstPersonテンプレートを使用してプロジェクト作成。
キー登録
「編集」→「プロジェクト設定」→「インプット」→「Action Mappings」にキー登録。
- CameraZoomToggle
- 左 Shift
ズーム用のカメラコンポーネントを追加
FOVを使用する形に変更するため、工程を削除
FirstPersonCharacterのBlueprintを開き、ズーム時に使用するカメラコンポーネントを追加する。
- ZoomCamera
- ロケーションを(1000, 0, 64)に変更
- Activation の Auto Activate のチェックを外す
カメラ切り替え用の処理を記述
イベントグラフを開き、Shift押下時にカメラを切り替えるように記述する。
「CameraZoomToggle」の入力が来た時に「FlipFlop」を使用し、「First Person Camera」と「ZoomCamera」のアクティブ状態を切り替えています。
SetFieldOfViewでカメラの視野角を変更しています。
視野角を小さくすることで描画される範囲が狭くなり、ズーム表示されます。
また、後述するWidgetからの参照用にZoom変数を公開しています。
ズーム時に表示するWidgetを設定
ここまででカメラのズーム機能は完了していますが、カメラズーム時にWidgetを表示する事でもっとそれっぽくできます。
FirstPersonWidgetという名前でWidgetを作成し、レベルブループリントに登録します。
この辺りは @aizen76 さんの記事を参考にするといいと思います。
デザインは以下の様な感じで、
Imageの「Behavior」→「Visibility」をHidden設定にしておき、バインドを以下の処理で登録します。
こんな感じになりました
UE4でカメラのズーム機能を作ってみた。 pic.twitter.com/rUZFVUq13p
— ほげたつ (@HogeTatu) July 24, 2015
GTX660 から GTX970 へ乗り換えたのでベンチマークを取ってみた
仕事を終えて家に着くのは日付が変わってから。
休日もあったり無かったり無かったり。
そんな生活を半年くらい続け、ようやく落ち着いたので自分へのご褒美として買ってきました。
MSI GTX 970 GAMING 4G MGSV グラフィックスボード ゲームクーポン付属モデル VD5680 GTX 970 GAMING 4G MGSV
- 出版社/メーカー: MSI COMPUTER
- 発売日: 2015/03/06
- メディア: Personal Computers
- この商品を含むブログを見る
表題にある通り、GTX660からGTX970への乗り換えです。
個人的にOculusを買っていて、OcuJamにも行っていた時期もあったのですが、GTX660だとコンテンツによっては常時75fpsを維持できずに酔ってしまうといった事態に陥っていたため、ちょっと財布には優しくないですが奮発しました。
GTX970のVRAM3.5G問題はあるけど、直近で4Kやる予定も無いし上限まで行く事はないだろうなーと。ただ2年は使う事を考えるとうーむ。
— ほげたつ(ドラゴン) (@HogeTatu) 2015, 6月 11
みたいに悩んだりもしましたが、まぁ欲しくなったらまた考えればいいかなと。
では本題のベンチマークです。
ド定番ですが 3DMark の FIRE STRIKE でベンチを取ってみました。
GTX660
GTX970
スコアは 4447 から 9369 に上昇!
乗り換え後はPhysicsが足を引っ張り始めましたね。
そろそろCPUも買い替え時ですかね。
とはいえ大幅上昇で満足です。
Oculus SDK 0.4 (Unity)でUIを表示する
ついに買いました。
DK2が出たら買おうとずっと待ってて、予約開始された時は迷わずポチリましたね。
早く届いて良かった。
もうこんなんですよ。
こころがぴょんぴょんしました。
では本題です。
夏だしUnityちゃんと肝試し的な事をしたいから作ってる。Unityちゃんには少し嘘ライトを当てて調整している。早くOculus来ないかな。 pic.twitter.com/gKQk6DtcYx
— ほげたつ(ドラゴン) (@HogeTatu) 2014, 7月 27
こんなことを思い、空いた時間でポチポチ作ってます。
DK2が届いたので組み込み、次はメッセージウィンドウでも出すかなと思ったが、やり方がわからない。
「そういえばスペースを押したらメニュー出てくるなぁ」と思い、流用できないかとソースを眺めてみるも、どうも専用で作られているようで、そのままでは使えそうにない。
仕方がないので作ることにしました。
NGUIでの描画をRenderTextureに描いて、OVRGuiObjectMainにTexture登録してからアタッチしてみているけど上手く描画されない…。クリア周りの問題だと思う。
— ほげたつ(ドラゴン) (@HogeTatu) 2014, 8月 3
こんな事でハマりつつも、なんとか完成。
出た。 RT @HogeTatu: NGUIでの描画をRenderTextureに描いて、OVRGuiObjectMainにTexture登録してからアタッチしてみているけど上手く描画されない…。クリア周りの問題だと思う。 pic.twitter.com/uRIEWxamfg
— ほげたつ(ドラゴン) (@HogeTatu) 2014, 8月 3
Awakeでクリア設定を書き換えているのは、エディタ上ではDepthOnlyで見たいからです。
(そうしないとUI以外が確認できなくなります)
全然関係ないですが、せっかく撮ったのでおまけ。
負けてばかりです。
杏最高。