UE4 WindowCapture機能をUMG対応しました

UMG対応 先日GitHubに公開しましたUE4向けのウィンドウキャプチャープラグインのWindowCapture2DにUMG対応を実施しました。 {{< x user=“ayuma_x” id=“1141689312255172608” >}} これで3D空間だけでなく、ウィンドウ内の固定位置にキャプチャー画像の貼り付けが可能になります。 使い方 UserWidgetに"WindowCaptureUMG"を配置します。 それだけです。 WindowCaptureUMGに設定するプロパティはActor版のWindowCapturePlaneと同じものになるため、ActorでもWidgetでも同じ設定方法で使えます。 Editor Widgetへの応用 応用としてEditorWidgetにも使えます。 ただし、現状EditorWidgetに使用するとコンパイルボタンを押したときに起こる終了→再初期化の処理が通常のUMGとは異なるせいでクラッシュしてしまいます。。。 現在直し方を調整中です。 ※ どうやらEditorWidgetを起動中にコンパイルすると落ちてしまうようです。一度EditorWidgetのウィンドウを閉じてからコンパイルすると落ちないことを確認しました。(2019/6/22) {{< x user=“ayuma_x” id=“1142066827872239617” >}} {{< x user=“ayuma_x” id=“1142074587980554240” >}}

2019-06-22 · 1 分 · 29 文字 · ayumax

UE4でウィンドウキャプチャー機能を作ってみた

WindowCapture2D 今回UnrealEngineで使えるウィンドウキャプチャープラグインをGitHub上に公開しました。 今はGitHubでのみ公開していますが、もう少し機能がまとまり次第マーケットプレイスにも出そうと思っています。 WindowCaptureへの思い ある時にVRコンテンツをUE4でWindows上のアプリケーションをVR空間に表示したくて色々調べてたのですが、中々ダイレクトでマッチする機能は探せず。 当時はそんなに時間もなかったのでUE4で実現するのをあきらめていました。 そんな中ネットを見ているとUnityならドンピシャの機能を作られている方がいて、試してみると普通にやりたい事ができてしまい感動した記憶があります。 Unity で Windows のデスクトップ画面をテクスチャとして表示するプラグインを作ってみた - 凹みTips 凄い凄いと思いながら、Unityでも実現できてるんだからUnrealでも作れるんじゃないだろうかと思い、トライしてみたのが始まりです。 Windowをキャプチャーする 私は25歳の時に今で言う「未経験からエンジニア」で転職したのですが、その時最初にやった業務がWindows上でのウィンドウキャプチャーでした。 C++, MFCで戦っていたのですが、当時はHDC? HWND?何それ?メモリDCってなに?って感じだったのを覚えています。 そのためウィンドウをキャプチャーするという技術には特別な思いがあります。 キャプチャー方法 私の知っているウィンドウキャプチャー方法は以下の2つです。 WindowのDCを取得してBitBlt WindowのDCを取得してPrintWindow 速度的にはBitBltの方がPrintWindowよりも早くて良いのですが、ChromeやUE4で作ったアプリケーションなどはBitBltではキャプチャーできません。 Windowを直接キャプチャーするのではなく、デスクトップのDCからキャプチャーして必要な領域をトリミングすると、どんなウィンドウでもキャプチャーできるのですが、 キャプチャーするのにディスプレイモニターのリフレッシュレート分待たされてしまう問題や、重なったウィンドウの背面側はキャプチャーできない等問題も数多くありました。 もう一つのPrintWindowも当初はChromeのキャプチャーはできないと思っていたのですが、Microsoftのヘルプに載っていない引数(PW_RENDERFULLCONTENT=2)を与えるとキャプチャーできるようになる発見がありました。 そこで今回はPrintWindowで作ってみる事にしました。 (その他にDirectXを使ってウィンドウキャプチャーする方法もあるそうですが、これはまだ試していません) UE4での実装 とりあえずTickの中でターゲットのウィンドウをキャプチャーしてテクスチャの中身を書き換えてみました。 テクスチャー(UTexture2D)の書き換えは以下のコードで実現できます。 auto Region = new FUpdateTextureRegion2D(0, 0, 0, 0, TextureTarget->GetSizeX(), TextureTarget->GetSizeY()); TextureTarget->UpdateTextureRegions(0, 1, Region, 4 * TextureTarget->GetSizeX(), 4, (uint8*)m_BitmapBuffer); TextureTargetがターゲットとなるTexture2Dで、 m_BitmapBufferはBGRA形式のピクセルバッファです。 この2行で動的にテクスチャーの書き換えができます。 実行するとうまくいったかのように見えたのですが、対象のウィンドウのサイズが大きくなるとカクツキが酷くなってしまい困りました。 {{< x user=“ayuma_x” id=“1137004503868223491” >}} そこで次はキャプチャーの部分のみTaskを使ってバックグラウンドで処理してみました。 void ACaptureMachine::Tick() { AsyncTask(ENamedThreads::BackgroundThreadPriority, [this]() { // キャプチャー処理を実施 }); } そうすると先ほどよりもフレームレートが上がり効果がありましたので、次に複数ウィンドウのキャプチャーにトライしました。 ...

2019-06-19 · 1 分 · 147 文字 · ayumax

UE4 MarketplaceにJsonパーサープラグインをリリースしました

EasyJsonParser 自作のUE4プラグイン3作目としてEasyJsonParserをリリースしました。 EasyJsonParser:ayumax:Code Plugins - UE4 マーケットプレイス これは2作目のEasyXMLParserとコンセプトは同じで、ブループリント上から簡単なアクセス方法でJson内の値を取得できます。 こちらもGitHubのほうにサンプルプロジェクトをアップロードしてますので、ご興味ある方は参考にしてください。 使い方 Json文字列 or Jsonファイルロードした後、アクセス文字列を指定して値の取得を行います。 アクセス文字列の指定 基本的には取得したい値までのパスをドットでつなげて指定します。 シンプルなケース 以下のシンプルなJsonから"prop"の値をとる場合のアクセス文字列はpropになります。 { "prop":"abc" } オブジェクトの階層になっている場合 以下のように階層になっている場合は、ドットでつなげてアクセス文字列を作ります。 以下のケースではobjというオブジェクトの中のpropプロパティを取りたいため、アクセス文字列はobj.propになります。 { "obj": { "prop":"abc" } } 配列が含まれる場合 以下のように配列になっている場合は、何番目のものを取りたいかを指定します。 例えば2個目のpropを取りたい場合は、obj[1].propとなります。 1個目のpropを取りたい場合は、obj[0].propとなります。 { "obj":[ { "prop":"abc" }, { "prop":"def" } ] } 型を指定しての値の取得 Jsonから値を取得するために、次の4つの関数が用意されます。 ReadInt(int) ReadFloat(float) ReadString(string) ReadBool(bool) 「AccessString」にはアクセス文字列を入力します。 「DefaultValue」にはデフォルト値を入力します。指定された値がJsonに存在しない場合は、デフォルト値が返されます。 オブジェクトの取得 値ではなくオブジェクトとして取得する “ReadObject"および “ReadObjects"メソッドもあります。 このメソッドで取得できるのはオブジェクトプロパティのみです。 ReadObjectは1つのノードオブジェクトを取得します。 ReadObjectsは複数のオブジェクトの配列を取得します。 ...

2019-06-15 · 1 分 · 68 文字 · ayumax

ObjectDeliverer v1.2.0リリース

ObjectDelivererのV1.2.0をリリースしました。 変更点は以下の2つです。 PacketRuleNodivisionを使用してUDPの受信を行うと無限ループしてしまう不具合修正 TCP/IPクライアントでサーバーが切断されると自動的に接続を試みるオプション追加 PacketRuleNodivisionを使用してUDPの受信を行うと無限ループしてしまう不具合修正 上記のようにPacketRuleNodivisionを使用してUDPの受信機能を使うと、一度受信したタイミングで無限ループに入ってしまう不具合が起きていましたので修正しました。 UDPの受信はPacketRuleNodivisionを使うことが一番多いと思うので、ホント致命的な不具合で申し訳ないです。 TCP/IPクライアントでサーバーが切断されると自動的に接続を試みるオプション追加 以前からTCP/IPクライアントを利用時にRetryフラグをONにすると、自動でサーバーが起動するまでConnectを繰り返す機能が実装されていました。 ただし、この機能はいったんサーバーと接続確立後にサーバー終了した場合は働かない仕様でした。 そこで今回新たにAutoConnectAfterDisconnectフラグを作成しました。 このフラグをONにすると、接続済みのサーバーとの接続がなくなった場合に自動でConnectを繰り返すようになります。 そのため、従来のRetryフラグを合わせて使うことで、サーバーとつながっていない時はいつでもConnectを繰り返すようになります。 常に接続を確立しておきたいケースに便利です。

2019-06-11 · 1 分 · 14 文字 · ayumax

UE4 MarketplaceにXMLパーサープラグインを出品しました

EasyXMLParser 本日Unreal EngineのMarketplaceにEasyXMLParserという名前でプラグインを出品しました。 前回リリースしたObjectDelivererに続いて2作品目となります。 前回は無料で出品したのですが、今回はお値段をつけさせていただきました。 使いやすさを重視して作りましたので、よろしければ是非ご検討ください。 このプラグインを使ったサンプルはGitHubに公開しています。 機能紹介 EasyXMLParserの機能を紹介します。 テキストの取得 テキストノードを取得するには、取得したい値のアクセス文字列を作成します。 アクセス文字列はタグ名をドットで結ぶことによって作成されます。 同じタグ名を持つノードが複数ある場合は、0から始まるインデックス番号を指定できます(例:[2] - > 3番目)。 インデックスを指定しないと、最初の要素が取得されます。 属性を取得するためのアクセス文字列は(アットマーク+属性名)で指定します。 型を指定しての値の取得 XMLから値を取得するために、次の4つの機能が用意されます。 ReadInt(int) ReadFloat(float) ReadString(string) ReadBool(bool) 「AccessString」にはアクセス文字列を入力します。 「DefaultValue」にはデフォルト値を入力します。指定された値がXMLに存在しない場合は、デフォルト値が返されます。 オブジェクトの取得 ノードを値としてではなくオブジェクトとして取得する “ReadElement"および “ReadElements"メソッドもあります。 ReadElementは1つのノードを取得します。 ReadElementsは複数のノードの配列を取得します。 XMLパース手法 XMLをロードする方法は2つあります。XMLファイルをロードするための “LoadFromFile"と、XML文字列をロードするための “LoadFromString"です。 バックグラウンドで解析を実行する非同期バージョンもあります。 XMLの次は 個人的にはたまにXMLをパースする機会があるので、今回プラグイン化してみました。 ただ現在はXMLよりもJsonの方が使われているような気もしています。 ということで、次のプラグインとしてJsonパーサーを出すつもりです。 このEasyXMLParserと同様の使い勝手で設計しておりMarketPlaceに現在審査してもらっています。

2019-06-10 · 1 分 · 42 文字 · ayumax

ObjectDelivererの共有メモリサンプル

共有メモリのサンプル 以前からGitHubにObjectDelivererのサンプルを用意していたのですが、共有メモリについては読み込み側しか実装しておらず処理が完結していなかったので新規で書き込み側も実装しました。 ここではサンプルの内容を簡単に紹介します。 概要 このサンプルではSceneCapture2Dで撮った画像をTexurueRenderTargetから取り出し、そこから共有メモリを経由して別のマテリアルに表示します。 まずはSharedMemoryレベルを開いてください。 全実装はBox Actorブループリント内にあります。 読み込み側の実装 共有メモリから読み込んだピクセルバッファを入れるテクスチャとマテリアルを用意します。 共有メモリの読み込み用ObjectDelivererのインスタンスを生成し処理を開始します。 共有メモリのバッファサイズは画像バッファサイズ(800x450x4 byte)を設定しています。 ReceiveDataイベント(共有メモリの中身に変化があった時におこるイベント)でテクスチャの中身を更新します。 書き込み側の実装 TextureRenderTargetから取得したピクセルバッファを入れておくバッファを用意します。 共有メモリへの書き込み用ObjectDelivererのインスタンスを生成し処理を開始します。 共有メモリのバッファサイズは画像バッファサイズ(800x450x4 byte)を設定しています。 Tickイベント時にTextureRenderTargetからピクセルバッファを取り出し共有メモリに書き込みます。 使い道 この例では1つのプロセス内で完結しているためあまり意味はないですが、 例えばUE4のプロジェクトを2つ用意して、片方は共有メモリへの書き込みを担当し、もう片方は共有メモリからの読み込みを担当することで映像の受け渡しができます。 共有メモリはTCP/IPやUDPと違ってネットワーク経由でのデータの受け渡しはできませんが、その分大容量のデータを高速に渡せるため映像などの重いデータのプロセス間通信に適していると思います。 ご興味ある方はぜひ試してみてください。

2019-06-06 · 1 分 · 25 文字 · ayumax

Editor Utility Widgetを使ってお絵かきして動的メッシュ生成機能を作った

Editor Utility Widget 今回UE4.22から利用できるようになった、Editor Utility Widgetという機能を試してみました。 Editor Utility Widgetを利用するとUMGとブループリントでエディタ拡張が簡単に作れます。 Editor Utility Widgetの基本的な説明はおかずさんの記事を参考にしました。 [UE4]エディタ上で動作するツール・エディタ拡張をUMGで簡単に作れる Editor Utility Widget について - Qiita つくったもの Editor Utility Widget上をマウスドラッグすることで線を一筆書きで書き、 書き終わった線に沿ってスプラインメッシュを生成する機能を作りました。 できたスプラインメッシュは、ボタンを押すとスタティックメッシュにできます。 {{< x user=“ayuma_x” id=“1134083916317380613” >}} Editor Scripting Utilities Pluginの有効化 このプラグインを有効にすると、Editor Utility Widgetからアセットの操作などができるようになります。 Widget上で線を引く 線を引く部分はUserWidgetを1つ作ってその中で実装しました。 まず、変数に線を引くための座標(Vector2D)の配列を用意します。 次にMouseDownで毎回座標配列を空っぽに。 MouseMoveでは座標の配列にマウスの座標をいれます。 ただし、すべてのMouseMoveイベントで処理すると点の数が多すぎるので前回格納した点から5pixel以上離れた場合のみ点を格納しています。 あとはOnPaintでDrawLinesを呼べば線が引かれます。 MouseUpでは線が引かれ終わったことを示すイベントを発火しています。 このイベントをEditor Utility Widgetが監視してメッシュ生成をこの後していきます。 Editor Utility Widgetの実装 次にEditor Utility Widgetを作成します。 先ほど作ったUserWidgetも配置します。 ComboBoxにメッシュ生成機能をもったActorの一覧を出したいので、 ComboBoxが開いたタイミングでActorの一覧を取得し追加しています。 またComboBoxの選択が変わった時にカレントのActorを設定しています。 先ほど作ったUserWidgetの線の引き終わりイベントを監視して、カレントのActorに線に沿った座標の配列を渡します。 スプラインメッシュ生成 スプラインメッシュを生成するActorを作っていきます。 SplineComponentを2つと、SplineMeshComponentの親になるSceneComponentを1つ追加しておきます。 SplineComponentは点の補正をするために贅沢に2つ使ってます。 UserWidgetの線が引き終わったタイミングで呼ばれる関数を作成していきます。 まずは、直前に生成されていたSplineMeshComponentを全て破棄し、SplineComponentの点も空にします。 次に渡されて点の配列をそのままSplineComponentの点に追加していきます。 1pixelを10cmとして設定しています。 次に1つ目のSplineComponentのラインに沿って等間隔の点を取り出し2つ目のSplineComponentへ点を追加していきます。 ここで2つ目のSplineComponentを作っているのは、等間隔に点を作ったほうがこの後作成するSplineMeshがきれいになるからです。 最後に2つ目のSplineComponentの点の位置とTangentを使ってSplineMeshComponentを作っていきます。 ...

2019-05-30 · 3 分 · 430 文字 · ayumax

UE4Pluginをマーケットプレイスに出すときのMarketplaceURL

先日2つ目のコードプラグインをマーケットプレイスに申請したのですが、 upluginへ各種プロパティを書いていく中で"MarketplaceURL"のみ空白で提出していました。 そもそもこのURLは実際にマーケットプレイスに公開されるまで決まらないURLだと思っていたので、 私は前回と今回の2回とも以下のフローでコードプラグインの申請をしていました。 MarketplaceURLは空白で提出 審査の人からメールで「upluginにこのURLを書いて再提出してね」を受け取る upluginを修正して再度パッケージ化→アップロードする 再申請 なんか助長なめんどくさいフローだなあと感じていたのですが、 2回ともこの方法でやっており、 ほっておいたら次の3回目もこの方法でやるつもりでした。 ただ、今日ふと審査待ちのプラグインのWebページを開いたら URLの末尾がupluginに書くMarketplaceURLの値になっているのに気づきました。 そっか、そりゃそうだよね。 こんなめんどくさいフローのはずはないよね。 ひょっとしたらちゃんとどこかに書いてあったのかもしれないのですが、見逃していたのかもしれません。 今まではこのURLを空白にしてたので、必ず再申請ありきのやり方だったのですが、 次からは1回で審査完了めざします。 ※2019/0615追記 実際にこの手法で申請したところ一度も修正することなく審査に合格できました。

2019-05-26 · 1 分 · 20 文字 · ayumax

.NET Core 3.0 WPFを試す(ノードベース電卓をつくってみた)

試してみた Visual Studio2019 + .NET Core 3.0の組み合わせではWPFが使えるぞということで新規プロジェクトを作成して試してみました。 とりあえず.NET Coreを使っているということを忘れて今までのWPFを使っている気持ちで書いてみて、どんな感じか見てみようと思います。 利用方法は色んな方が紹介されていますが、Visual Studio2019と.NET Core 3.0をインストールして、Visual Studioのオプションから「プレビューの.NET Core SDKを使用」にチェックをONすると使えるようになります。 .NET Core 3.0が正式版になればこのチェックはいらなくなると思います。 C# 8.0 null許容参照型 同時にC# 8.0で導入されるnull許容参照型も試してみました。 今回は新規プロジェクトを作って試すので、.csprojに以下のように記載をしてプロジェクト全体でnull許容参照型を有効にしています。 <propertygroup></propertygroup> <outputtype></outputtype>WinExe <targetframework></targetframework>netcoreapp3.0 <usewpf></usewpf>true <langversion></langversion>8.0 <nullablecontextoptions></nullablecontextoptions>enable この設定にすることで、今までの参照型の書き方ではnullをいれることができなくなります。 またnullである可能性がある変数にアクセスすると警告を出してくれるようになります。 作ったもの 新規でプロジェクトを作るので、何かテーマを決めようと思い、 仕事で触っているUnreal Engine(UE4)や最近注目しているHoudiniというツールでノードベースの作成環境をよく見ているので「ノードベースタイプのUI」をテーマにしました。 ただノードをつなげるだけだと面白くないので、電卓機能をいれています。 作ったものは、この記事を書いた時点で以下のような感じです。 現状ノードをつなげて足し算と引き算ができます。 {{< x user=“ayuma_x” id=“1127130209390477312” >}} プロジェクト一式はGitHubで公開しています。 ※ このノードベース電卓ですが、まだまだ作成中の段階のため頻繁に修正しています。 NuGetからの参照 今回NuGetからは以下の4つを参照に加えています。 Extended.Wpf.Toolkit gong-wpf-dragdrop Microsoft.Xaml.Behaviors.Wpf ReactiveProperty この中で、Extended.Wpf.ToolkitとMicrosoft.Xaml.Behaviors.Wpfは.NET Core 3.0にまだ対応していないようで以下の警告がでました。 NU1701: パッケージ &#39;Extended.Wpf.Toolkit 3.5.0&#39; はプロジェクトのターゲット フレームワーク &#39;.NETCoreApp,Version=v3.0&#39; ではなく &#39;.NETFramework,Version=v4.6.1&#39; を使用して復元されました。このパッケージは、使用しているプロジェクトとの完全な互換性がない可能性があります。 NU1701: パッケージ &#39;Microsoft.Xaml.Behaviors.Wpf 1.0.1&#39; はプロジェクトのターゲット フレームワーク &#39;.NETCoreApp,Version=v3.0&#39; ではなく &#39;.NETFramework,Version=v4.6.1&#39; を使用して復元されました。このパッケージは、使用しているプロジェクトとの完全な互換性がない可能性があります。 とりあえず使っている範囲での動作には問題がないのと、.NET Core 3.0はまだプレビュー版なので気にしない事にしています。 ...

2019-05-13 · 2 分 · 246 文字 · ayumax

UE4マーケットプレイスにだしているコンテンツを更新する際の注意

自分がプラグインを更新する際に少し迷ったのでメモします。 C++によるコードプラグインは特に何度かバージョンアップすることになると思いますが、その際の注意点です。 既に出品済みEngineバージョンのコンテンツを更新する際は、以下の画面のProject File Linkを前回と異なるリンクURLにする必要があります。 このURLを前回と同じにするとコンテンツが変わったという通知がいかないようです。 私はMicrosoftのOneDriveを使っていますが、クラウドのファイルを上書きすると前回と同じ共有リンクURLになるため、一度共有を解除してから再度共有することで異なるURLを発行しました。

2019-05-08 · 1 分 · 7 文字 · ayumax