Hi there 👋

About Me

Hi, I’m ayumax! I’m a software engineer specializing in application development with C#, Unreal Engine code plugins, and cloud services using AWS.

On this blog, I share technical notes and daily topics related to my work and interests.

Unreal Engine Code Plugins

I publish code plugins for Unreal Engine on Fab. Feel free to check them out if you’re interested!

Froolaを公開しました

Froola https://github.com/ayumax/Froola Froolaは私の作成したUnreal Engineのコードプラグインを複数プラットフォーム同時にテストしたり、プラグインパッケージを生成したりするためのツールです。 もともと私はUEのプラグインをいくつか作っていたのですが、それらはWindows, Macのプラットフォームに対応していたため毎回パッケージの作成が面倒でした。 というのも、Windows環境ではWindows, Android, Linux向けにパッケージを作れますがMac, iOS向けには作れません。 そのため、WindowsとMacの両環境でプラグインのビルドをしたあとに、それらを組み合わせて1つのプラグインパッケージを作っていました。 Unreal Editorにそのような機能があればよかったのですが、私の調べた範囲では見つからなかったので毎回手動で組み合わせていました。 でも、どうせならこれらを1つのツールとしたほうがうれしい人もいるかもしれないと思い、Froolaを作りました。 GitHub ActionsなどのCI/CD機能との比較 上記のようなことをしたい場合、通常ならGitHub ActionsなどのCI/CD機能を利用することをまず思いつきます。 しかし、Unreal Engineをクラウドで動作させるのは主に金銭的に大変です。 Unreal Engineの1つのバージョンはだいたい50GBくらいになり、複数バージョン用意するとさらにストレージは必要になります。 またCPUもそこそこパワーがあるものが必要になるため、実行環境を用意するのが大変でした。 またMacはAWSなどでEC2を借りれたりもするのですが、最低1日単位でかなり高いです。ほかにもいくつかMacのクラウドサービスもありますが、それらも高価でした。 そこでおそらく多くの人はオンプレのサーバーをself-hosted runnerとして使っているのではないかと思います。 ただ個人でpublicなリポジトリを扱っている場合はセキュリティの観点からself-hosted runnerは避けたかったので、そうなると自分の開発PCで直接ビルドするのが一番よいなという結論になりました。 Froolaの構成 Froolaはマルチプラットフォーム対応のプラグインパッケージを生成しますが、やっていることは単純でWindowsとMacの両環境でプラグインをビルドしてから、それらを組み合わせて1つのプラグインパッケージを作っています。 またLinuxビルドは考えた結果WindowsのUEを使わずにLinuxのUEをDocker経由で使うようにしています。これについての理由は後述します。 そのため、以下のようなフローで動きます。 Windows環境にプラグインプロジェクトをリモートリポジトリからCloneする Windows環境にWindows, Linuxビルド用のディレクトリをつくりそこにリポジトリのファイルをコピー MacにSCPで(1)でCloneしたリポジトリのファイルをコピーする WindowsのUEと、Windows上のDockerのUEを同時に起動してプラグインをビルドする MacにSSHでMacのUEを使ってプラグインをビルドする MacでビルドしたパッケージをSCPでWindowsにダウンロード Windows, Mac, Linuxのビルドしたパッケージを組み合わせて1つのプラグインパッケージを作成する sequenceDiagram participant Windows participant Windows(Docker) participant Mac Windows->>Windows: リモートリポジトリからClone Windows->>Windows: Windows, Linuxビルド用ディレクトリ作成&ファイルコピー Windows->>Mac: SCPでリポジトリファイルをコピー Windows->>Windows: UEでプラグインビルド Windows->>Windows(Docker): Docker内UEでプラグインビルド Mac->>Mac: SSHでMacのUEを使いプラグインビルド Mac->>Windows: MacでビルドしたパッケージをSCPでWindowsにダウンロード Windows->>Windows: 各OSのビルドパッケージを組み合わせて1つのプラグインパッケージを作成 これを見るとまったく複雑なことはやっていないことがわかると思います。 シンプルイズベストです。 というかこれ以外にやれる方法は現状ないと思います。せいぜいWindwosのUEでLinux向けも一緒にビルドするくらい。 自動テストの存在 今回Froolaを作るにあたって、パッケージをつくるだけでなくテストの実行も各プラットフォームで行えるようにしました。 ...

2025-05-05 · 2 分 · 420 文字 · ayumax

HUAWEI FreeBuds 3 vs FreeBuds 3i

FreeBuds 3とFreeBuds 3i FreeBuds 3とFreeBuds 3iはHUAWEIから販売されているワイヤレスイヤホンです。 FreeBuds 3の後にFreeBuds 3iが出たので3iの方がパワーアップしているような気がしますが、どちらかというとノイズキャンセリング以外の機能はパワーダウンしているような感じです。 値段もこの記事を書いている時点でAmazonで3が20000円程度、3iは13000円程度です。 このことからもFreeBuds 3の方が力をいれて作られたことが分かります。 私はずっとFreeBuds 3を使っていたのですが、 FreeBuds 3iを購入したので、それまで使っていたFreeBuds 3と比べてみました。 様々な機能やスペックについての比較は、色んな所でされているので今更感があるので個人的な感想ベースでの比較となります。 2つの製品については以下の公式ページをご覧ください。 HUAWEI FreeBuds 3,HUAWEI Kirin A1チップセット、インテリジェントノイズキャンセリング│HUAWEI Japan HUAWEI FreeBuds 3i - HUAWEI Japan 着け心地 まずは耳へ付けたときの装着感の違いです。 これに関してはFreeBuds 3の完全に勝利でした。 この辺に関しては人による違いが物凄く大きくでる部分だと思うので参考までにしてください。 まず、この2つのモデルは開放型とカナル型という大きな違いがあるため、以下のように見た目も大きく異なります。 そのため、FreeBuds 3は耳に優しくはまる感じなのですが、FreeBuds 3iのほうはグリグリっと押し込む必要があります。 3iをつけた後に3を付けると、ホントに軽くとまっている感じで耳への負担も少なく優しい感じがします。 ただ、これは耳の形状にもよって変わると思うので全ての人で同じ感想は得られないかもしれないです。 色々な人のレビューを見ていると、3は「直ぐに耳から落ちてしまう」という人もいるみたいですが、私はランニングの時に着けても全然外れることなく使えているので、よほど耳にフィットしているようです。 ケースの持ち運び 自分が大分気になっている点としてケースの持ち運びがあります。 下の写真は左がFreeBuds 3で右がFreeBuds 3iです。 見ていただくと分かる通り、3iの方が厚みがあります。 私は普段ズボンの左ポケットに入れる事が多いのですが、その時に3iの厚みは大分気になっちゃいます。 横幅をもう少し広げてでも厚みは抑えてほしかったなあという感想です。 ノイズキャンセリング この2つのモデルは両方ともアクティブノイズキャンセリングの機能をもっています。 このノイズキャンセリングの比較をすると、これはカナル型である3iの圧勝です。 電車に乗っている時のガタンガタンという音で比較すると、FreeBuds 3が体感20%くらい音が小さくなるのに比べてFreeBuds 3iは60~70%くらいは軽減されていると思います。 そもそも3のほうは開放型にノイズキャンセリングを載せているだけでも凄いので、これはしょうがないは思います。 3iの方は耳へ付ける角度でもだいぶノイズキャンセリングの感じが変わってくるので、どの角度が一番静かになるかは最初に検証したほうがより良く使えると思います。 あと細かな点として、3のほうは使うたびにノイズキャンセリングがOFFの状態に戻ってしまうのですが、3iの方は前回のON,OFF状態を覚えていてくれるのでそこも異なる点です。 ただこれは一概にどちらが良いとは言えないなあとも思えてきました。 というのも前回使った時がちょい前とかだと、前回ノイズキャンセリングをONにしたまま終えたかどうか覚えておらず、3iを装着してから今どっち(ノイズキャンセリングON or 外部音取り込み)だろうと思ったことが既に何度かあります。 3の方は毎回OFFですから、イヤホンのダブルタップをしてONにするというルーチンを毎回すればよいので悩むことはないです。 また3の方はアプリでノイズキャンセリングの調整を行う必要がありますが、3iは必要ありませんというかアプリメニューになかったです。 スマホとの接続 私はスマホは同じHUAWEIのP30 Proを使っています。 個人的にBluetoothを使ったデバイスはブチブチ切れるのが凄いストレスなので、可能な限り同じメーカーで揃えたいというのがあるので今は両方HUAWEIにしてます。 ...

2020-09-20 · 1 分 · 100 文字 · ayumax

WinUI 3 Preivew1のプロジェクトをPreview2に更新する

WinUI 3 Preview 2 気づかずに半月程たってしまいましたが、WinUI 3のPreview2がでてました。 WinUI 3 Preview 2 (2020 年 7 月) なので、以前WinUI 3 Preview1を使って作成した以下のWinUI3 DesktopプロジェクトをPreview 2に更新してみました。 今回はその記録です。 基本的に公式の説明通り進めていっただけなので有用な情報は少ないです。 環境の更新 公式ページの記述に従い環境を確認していきます。 開発用コンピューターに Windows 10 バージョン 1803 (ビルド 17134) 以降がインストールされていること Windows10 2004なのでOK. Visual Studio 2019 バージョン 16.7 Preview 3 のインストール インストール済みのVS2019 Previewのバージョンを確認してみると、16.7.0 Preview 3.1でした。 なのでこのままいくことに。 更新プログラムの確認をしたところ、16.8.0 Preview 1.0がありましたが、前回.NET 5のバージョンを最新にしたことでWinUI 3 Preview1の起動が失敗するようになったのでむやみに最新にするのはやめました。 .NET 5 Preview 5 WinUI3 Preview2では.NET 5のPreview5に対応したみたいです。 現状の最新を確認したところ、Preview7がありましたが確実に動作させるためにPreview5にしておきます。 ただし、今回は公式ページの説明に「Preview5よりも新しいのを入れないで」という但し書きが無かった(前回はあった)のでひょっとしたらPreview7でも動くかもしれません。 WinUI 3 Preview 2 VSIX パッケージのインストール VSへの拡張機能をいれます。 ただダウンロードしてインストールしてみたところ、既に入っていますと表示されていたのでPreview1から変わってないと思います。 ...

2020-08-07 · 1 分 · 120 文字 · ayumax

UE4 Windowsパッケージにおいてのアンフォーカス時の対応(Sound再生、GamePadの入力)

フォーカスがないときの挙動 私はお仕事でUE4をゲーム以外の用途で使っているのですが、Windowsで他のアプリケーションと一緒に使うことが多いです。 よくあるパターンがUE4で表示部分を作り、WPFでコントローラーのようなものを作り組み合わせて使うパターン。 このパターンではどうしてもフォーカスはWPFアプリケーション側にくるので、UE4のウィンドウにはフォーカスが無い状態になります。 そうすると以下のような困ったことが起こりました。 音が聞こえない GamePadの入力がとれない これらについて中々対策が見つからなかったのですが、Engineソースを確認したところ2つとも対策が見つかりましたので覚書として書いておきます。 なお、この記事の対処をしたのは4.24の環境ですが、4.25でもその部分の実装は変わってなさそうなので同じ対応でよいのかと思っています(4.25では動作確認まではしてません) アンフォーカス時の音の再生 WindowsPlatformApplicationMisc::PumpMessagesにて以下の記載を見つけました。 // if its our window, allow sound, otherwise apply multiplier FApp::SetVolumeMultiplier( HasFocus ? 1.0f : FApp::GetUnfocusedVolumeMultiplier() ); SetVolumeMultiplierは音のボリュームをセットする関数のようですが、ここでフォーカス有りの場合は1.0を、そうでない場合はGetUnfocusedVolumeMultiplierの値を使っています。 そしてGetUnfocusedVolumeMultiplierが返す値を調べると0になっておりました。 なので聞こえないんだなあ。 ただ、この値の初期値はConfigからとられていることが分かります。 static bool GUnfocusedVolumeMultiplierInitialised = false; float FApp::GetUnfocusedVolumeMultiplier() { if (!GUnfocusedVolumeMultiplierInitialised) { GUnfocusedVolumeMultiplierInitialised = true; GConfig->GetFloat(TEXT("Audio"), TEXT("UnfocusedVolumeMultiplier"), UnfocusedVolumeMultiplier, GEngineIni); } return UnfocusedVolumeMultiplier; ということで、以下の設定をConfig/DefaultEngine.iniに書いてUnfocusedVolumeMultiplierの値も1.0になるようにして動作を確認しました。 [Audio] UnfocusedVolumeMultiplier=1.0 アンフォーカス時でも音が聞こえてきて成功です。 アンフォーカス時のGamePadの入力 UE4でGamePadの入力はWindowsではXInputというAPIを使っています。 なので、そこから検索するとXInputInterfaceというクラスが見つかりました。 中身を確認するとXInputのAPIを呼んでいるのでここがGamePadの入力を受け取っている可能性が高いです。 次にXInputInterfaceを使っている箇所を探し、FWindowsApplicationにて使われていることが分かりました。 するとFWindowsApplication::PollGameDeviceStateにてXInputの入力イベントを発火していそうです。 更にこの関数はFSlateApplication::PollGameDeviceState()から呼ばれています。 FSlateApplication::PollGameDeviceState()の中身を見るとifでガードされています。 if( ActiveModalWindows.Num() == 0 && !GIntraFrameDebuggingGameThread && (!bRequireFocusForGamepadInput || IsActive())) { // Don't poll when a modal window open or intra frame debugging is happening PlatformApplication->PollGameDeviceState( GetDeltaTime() ); } ここには3つの条件がありますが、最後のIsActive()はフォーカスを持つことのような気がします。 しかにここにbRequireFocusForGamepadInputというダイレクトで関わりが深そうな変数があります。 ...

2020-05-31 · 1 分 · 118 文字 · ayumax

UPropertyからFPropertyへの変化(UE4 4.25)

Unreal Engine 4.25 Preview 先日UE4の4.25のPreviewがダウンロードできるようになりました。 (この記事を書いている段階ではPreview3になっています) その内容は以下のページに記載されています。 Unreal Engine 4.25 Preview - Unreal Engine Forums たくさんある更新内容の中で、以下の項目が目に留まりました。 (FProperty Refactor…の部分です) 内容は「4.25からはUPropertyはFPropertyとなってUObjectではなくなりました」というものです。 今までUPorpertyはUObjectを継承していました。 UE4ではUObjectを継承しているクラスはUから始まる命名規則があります。そのためUPropertyというクラス名でした。 参考 [コーディング標準](https://docs.unrealengine.com/ja/Programming/Development/CodingStandard/index.html) それがUObjectを継承しなくなった(FFieldというクラスを継承するようになっています)ため、FPropertyというクラス名に変わったということでした。 UPropertyとは そもそも今回変更されたUProperty(FProperty)とは何なのかというと、UE4のプロパティシステムによって作られたC++クラスのメンバー変数または関数の引数の情報になります。 詳細は以下の公式ページに詳しく説明されています。 参考 [Unreal Property System (Reflection)](https://www.unrealengine.com/ja/blog/unreal-property-system-reflection) 更にUPropertyはプロパティの型によって、UStringPropertyやUBoolPropertyなどに派生されています。 UE4のエンジン内部では色々な用途に使われていますが、我々UE4を使う側の立場では、例えば以下のようなことをしたい時に使うことになります。 ブループリントで定義したオブジェクトのプロパティにC++側からアクセスしたい オブジェクトの独自のシリアライザを作りたい オブジェクトのプロパティをプロパティ名を指定して触りたい このようにUPropertyを使ってUE4のプロパティシステムを使うと、より柔軟にオブジェクトを操作する仕組みが構築できます。 (参考)オブジェクトの全てのプロパティの値を取得する例 以下のコードはObjの全てのプロパティの値を取得しています。 (※ この例では全てのプロパティの型はuint8であるという前提です) for (TFieldIterator<UProperty> PropIt(Obj->GetClass()); PropIt; ++PropIt) { UProperty* Property = *PropIt; // プロパティ名を取得 FString PropertyName = Property->GetName(); // プロパティの値を取得 uint8 CurrentPropAddr = *(PropIt->ContainerPtrToValuePtr<uint8>(Obj)); } なぜFPropertyに変更されたのか 全部の情報を追い切れてないので個人的な想像を多分に含みますが、UObjectで無くすことによりGC(ガベージコレクション)の管理対象外にしたかったのが大きな理由なのかなと考えています。 UObjectとしてインスタンスをメモリに確保すると、GCが適切なタイミングでインスタンスを破棄するべきかどうかをチェックします。 チェックの結果破棄するべきとなったインスタンスは破棄されることになります。 プロジェクト全体でUObjectのインスタンス数が多いと、このGCが破棄対象をチェックする際の検索時間が多くなってしまいます。 (調べる対象の個数が絶対的に多くなってしまうため) ...

2020-03-22 · 1 分 · 140 文字 · ayumax

ObjectDeliverer Ver 1.5.0リリース ObjectのJsonシリアライズ機能の強化

本日ObjectDelivererのVer 1.5.0をマーケットプレイスにリリースしました。 ObjectDeliverer:ayumax:Code Plugins - UE4 マーケットプレイス 今回の実装内容はObjectのJsonシリアライズ機能の強化です。 これについては以前の記事に現状の課題として書いていました。 UObjectをJsonにシリアライズしよう - AYU MAX 今回のリリースでは上記課題を改善する機能実装になります。 実装項目 以下の2項目を対応しました。 プロパティ名の変換 How to change property name when serializing UObject with Json(Version 1.5.0 or later) · ayumax/ObjectDeliverer Wiki · GitHub シリアライズ対象のクラスにIODConvertPropertyNameインターフェイスを実装することで、プロパティ名の変換ができるようになりました。 使用例) // 変換前 { "Prop2": 1, "ObjProp": { "ValueB": 0, "ValueA": 0 }, "ObjProp2": { "ValueC": "abc" } } // 返還後 { "IntProperty": 1, "ObjectPropertyA": { "ValueB": 0, "ValueA": 0 }, "ObjectPropertyB": { "ValueC": "abc" } } この機能を使うことで以下のようなことが可能になります ...

2020-01-24 · 1 分 · 140 文字 · ayumax

2019年の振り返り

今年は早かった。あっという間に終わった1年でしたが、去年もやったように1年を振り返ってみようと思います。 去年の振り返りはこちら 1年の振り返りと新年の抱負 - AYU MAX 何をした? 月 やったこと 1月 ObjectDelivererを作った 2月 ObjectDelivererをマーケットプレイスに出品した 3月 VRのコンテンツを作って会社にプレゼンした 4月 VRのお仕事Get 5月 Pimax 8K試した .NET Coreを試した 6月 EasyXMLParserをマーケットプレイスに出品した EasyJsonParserをマーケットプレイスに出品した 7月 WindowCapture2Dをマーケットプレイスに出品した 8月 UE4 + ARKitでARコンテンツ作成 9月 IL2C + UE4の実験 ARのお仕事Get 10月 .NET Conf 2019 meetup in AICHIでLTした 11月 疲れて抜け殻 12月 C#とUE4のアドベントカレンダー記事を1つずつ投稿 VR開発 今年の大きな出来事として仕事でVR開発を始めたことがあります。 世間的にはVRはもうそこまで珍しいものではありませんが、弊社では初の試みなので周りからは色々(期待やら不安やら)言われてましたが、一定の成果は残せました。 これも今後どこまで広げれるかっていうのは課題なので、来年も引き続き頑張ることになります。 AR開発 今年はUE4とARKitでARの開発も始めました。こちらはUE4でARKitを使って開発する基本をなぞっただけの段階ですがやりたい事は全てできたので満足してます。 来年以降どうやって業務に取り入れるのか考えたいなあと思ってます。 あとモバイル端末だけでなくHoloLensとか、Magic Leapもさわりたいですね。 あと、個人開発でもなんかやりたいなあと。 UE4 マーケットプレイス プライベートの活動としてはマーケットプレイスに出品したことが大きい出来事です。 年のはじめに自分でも出品する事はできるのかなあと思って調べはじめ、なんやかんやで4つのコードプラグインをリリースしました。 どれも魂込めて作ってますので、ぜひたくさんの方に使っていただけたら嬉しいなあとおもいます。 あとオープンソースにしているプロジェクトもあるので、GitHub上での他の人とのやりとりが楽しかった。 英語なのでGoogle翻訳様の力を借りないと、会話が成立しないのですが、おかけで翻訳しやすい日本語の生成力があがった気がします! マーケットプレイスでの評価もとても励みになっているのでありがたいです。 反省点としては、調子に乗って4つもリリースしたことでメンテナンスが追いついてない事です。 どのプラグインにも実装したいけど、できていないネタがあるので、来年はそこをやっていきたいなあと思ってます。 登壇 今年は当初どこかで2回は登壇することを目標にしてたのですが、結果としては1回のみでした。 でもそういう機会がもらえただけでもありがたいですし、少しは成長できたと思うので今後も引き続き機会があればやりたいなあと思います。 ...

2019-12-31 · 1 分 · 74 文字 · ayumax

UE4+ARKitで作る遠隔タッチディスプレイ

先日頭の中にあったアイデアを形にしたくて、↓こんなものをつくりました。 {{< x user=“ayuma_x” id=“1210122895520718849” >}} iPadの上を指でなぞると、iPadの中のディスプレイに線が引かれているのですが、iPadを取り除くと実際のディスプレイにも同じ線が引かれています。 これは初見だと混乱するかもしれませんが、実はiPad側には何も表示は加えていません。iPadのディスプレイにはカメラの映像のみ表示しています。 何をしたかったのか? 少し前に仕事でiPad使ってARのコンテンツを作っていたのですが、その時に感じた「AR=[何か表示を重ねる]以外の使い方を考えてみたいな」と思ったのがきっかけです。 今回行った内容も多分誰かが似たようなことはやっているのだとは思いますが、「自分で考えてアイデアを形にすることに意味がある」ということでやってみました。 今回の実験においてiPadは入力機器として使います。 ARKitには画像検知や物体検知の機能があり、これをうまく使うことで遠隔タッチディスプレイを作ろうというアイデアです。 やるべきこと このアイデアを形にするためにやるべきことを以下にまとめました。 今回iPadのアプリケーションはUE4(4.24)のHandheld AR ブループリント テンプレートをベースに作ります。 iPadに映っているディスプレイの位置、角度を知る iPadに触れた指の位置をディスプレイの相対座標として知る iPadからPC側に座標を送る PC側で送られた座標にしたがって線を引く iPadに映っているディスプレイの位置、角度を知る まずはディスプレイの位置を知る必要があります。 位置を知る方法として「画像を利用したマーカー方式」と「物体検知」の2通りを考えましたが今回は物体検知を選びました。 UE4+ARKitでの物体検知の使い方は以前記事にしているので、興味ある方はみてください。 UE4でARKitの物体検出機能を使う - AYU MAX まずはディスプレイをスキャンして検知するためのデータづくりを行ったのですが、ディスプレイの形状に特徴点が少なく満足する結果が得られませんでした。 そこでディスプレイ横のごちゃごちゃした所の検知データを作成し、ディスプレイの位置、角度はそのポイントからの相対位置で判断するようにしました。 当然ですが、この方法ではディスプレイとの位置関係を変えてしまうと破綻します。 ↓スキャンしているところ スキャン後にディスプレイの位置、角度を知るのは上記した以前の記事の内容そのままです。 iPadに触れた指の位置をディスプレイの相対座標として知る 次にiPadに触れた指の位置を知るにはどうすれば良いか考えます。 今回使っているUE4のARテンプレートの中の実装には、タッチしたポイントにActorがあるかどうか調べるロジック(BP_ARPawnのWorldHitTest関数)があります。 これをちょっといじってディスプレイの位置を知ることを考えました。 まず現実世界のディスプレイと同じ大きさになるような板メッシュを用意してレベルに配置しておきます。このメッシュは見える必要はないので透明なマテリアルをつけときました。 次に毎Tick, ARKitが現実のディスプレイを検知した位置、角度にこのメッシュを移動させます。 次にWorldHitTest関数の中を見ると、LIneTraceForObjectsというノードが使用されているのが分かります。 LIneTraceForObjectsは指定した2点の間に3Dオブジェクトがあるかどうかの判定ができます。 このノードと直前に配置されているDeproject Screen to Worldを組み合わせると、タッチしたときのiPad上のスクリーン座標(x, y)から触れている場所に配置してある3Dオブジェクトが特定できます。 この仕組みを使うと、先ほど配置したメッシュを指で触れているかどうかということが分かります。 ただし、今回知りたいのはディプレイのどこを触れているかなので、もう少し詳細な情報が必要です。 そこでLIneTraceForObjectsで返される値をFind Collision UVに入れる部分を足してみました。 これで触れた3Dオブジェクトの表面のどの部分(UV座標)という情報までとれます。 ※ Find Collision UVを使うにはProject SettingsでSupport UV From Hit ResultsのチェックをONにする必要があります。(多分ONにすると処理負荷は上がっちゃいます) iPadからPC側に座標を送る iPadからPC(Windows)へはソケット通信(UDP)で座標を送ることにします。 UDP送信にはObjectDelivererを使います。 ObjectDelivererについては過去記事みてください。 まずは送信するための入れ物を作ります。といっても簡単で以下のようなブループリントを定義します。TouchPositionというオブジェクトの名前にしました。 ...

2019-12-28 · 1 分 · 86 文字 · ayumax

UObjectをJsonにシリアライズしよう

この記事はUnreal Engine 4(UE4) Advent Calendar 2019の20日目の投稿記事です。 Unreal Engine 4 (UE4) Advent Calendar 2019 - Qiita 私がマーケットプレイスに公開しているObjectDelivererというプラグインがあります。 今回の記事はこのプラグインに実装している「オブジェクトをJsonにシリアライズする機能」について書きます。 例えばこんなVariablesを定義したブループリント(Objectを継承)があるとすると、 こんな感じのJson文字列に変換されます。 { "IntValue":0, "BoolValue":false, "StringValue":"ABC" } Jsonは文字列で表現されるので、そのままテキストファイルに保存することもできます。 また文字列なので人間の目で見ても中身が分かりやすいです。 このJsonをオブジェクトに復元する機能も作ることで、Jsonを介してオブジェクトの保存-復元ができるようになるのです。 ObjectDelivererではこのJson文字列を通信に乗せて送受信することで、オブジェクトを別の場所(別のアプリケーション)に届けることができています。 UE4におけるJsonの取り扱い UE4には標準でJsonとJsonUtilitiesというモジュールがあります。 Jsonモジュール Jsonの読み書きをサポートするモジュールです。ただしブループリントでは使用できずC++のみサポートされています。 こんな感じで使えます。 Jsonオブジェクト→Json文字列 // FJsonObject(Jsonデータの入れ物)を作成 TSharedPtr&lt;FJsonObject> jsonObject = MakeShareable(new FJsonObject()); // jsonObjectにプロパティを追加 // FStringにJsonを書き込むためのWriterを作成 FString OutputString; TSharedRef&lt;TJsonWriter&lt;>> Writer = TJsonWriterFactory&lt;>::Create(&amp;OutputString); // JsonをFStringに書き込み FJsonSerializer::Serialize(jsonObject.ToSharedRef(), Writer); // OutputStringにJson文字列が入っているので何かする Json文字列→Jsonオブジェクト // json文字列が入っているFString FString jsonString; // FStringからJsonを読み込むためのReaderを作成 TSharedRef&lt;TJsonReader&lt;TCHAR>> JsonReader = TJsonReaderFactory&lt;TCHAR>::Create(jsonString); // FJsonObject(Jsonデータの入れ物)を作成 TSharedPtr&lt;FJsonObject> JsonObject = MakeShareable(new FJsonObject()); // Json文字列からJsonオブジェクトに読み込み FJsonSerializer::Deserialize(JsonReader, JsonObject); // jsonObjectからプロパティを取り出して何かする Jsonオブジェクトの値のGet, Set TSharedPtr&lt;FJsonObject> JsonObject = MakeShareable(new FJsonObject()); // 値のセット JsonObject->SetNumberField("IntValue", 1); JsonObject->SetBoolField("BoolValue", true); JsonObject->SetStringField("StringValue", "ABCDEFG"); // 値の取得 int32 intValue = JsonObject->GetIntegerField("IntValue"); bool boolValue = JsonObject->GetBoolField("BoolValue"); FString stringValue = JsonObject->GetStringField("StringValue"); // このほかArrayやObjectプロパティもGet, Setできます 上記パターンを知っていれば、だいたいのケースで対応できると思います。 ...

2019-12-20 · 2 分 · 355 文字 · ayumax

.NET Coreでアセンブリをアンロードする

アセンブリをアンロードする仕組み この記事は C# Advent Calendar 2019 の10日目です。 私がお仕事で作っているアプリケーション(.NET Framework製)にユーザープラグイン(DLL)読み込み機能を持つものがあります。 これは利用者がルールに則ったDLLを自分で作ることで、開発ツールに機能を足すことのできる機能です。 この機能は開発ツール側でいったん該当のDLL達をロードし問い合わせを行い、読み込む必要のないDLLはアンロードする処理が入っています。 この開発ツールを.NET Coreに移植する際に.NET Frameworkとは異なる手法を使う必要があったので紹介します。 AppDomainは使えない .NET Frameworkではアセンブリのアンロードを行うにはAppDomainを使いました。 アプリケーション規定のAppDomainの他にドメインを生成し、その中でアセンブリをロードします。 インターフェイスなどを経由してアセンブリの機能を利用し終わったら、AppDomainのUnloadメソッドをコールしてドメインごとアセンブリをアンロードします。 ただし.NET CoreではAppDomainは1つしかサポートされていないため、この方法は使えません。 その代わり.NET Coreではアセンブリのアンロードを行うために AssemblyLoadContextが用意されているので、今回はこれを使ってみます。 AssemblyLoadContextとは AssemblyLoadContextとはAppDomainと同様にアセンブリ読み込みを閉じたスコープ内で行えるものです。 この中にロードしたアセンブリは、AssemblyLoadContextのUnloadメソッドをコールすることでまとめてアンロードできますが注意することがあります。 注意点1 isCollectibleをtrueにする AssemblyLoadContextのコンストラクタ引数にあるisCollectibleはtrueにする必要があります。 これはパフォーマンスの観点からデフォルトではfalseになっているためです。 falseのままUnloadをコールすると例外が発生します。 System.InvalidOperationException HResult=0x80131509 Message=Cannot unload non-collectible AssemblyLoadContext. Source=System.Private.CoreLib 注意点2 アンロードは強制的ではなく協調的である AssemblyLoadContextのUnloadメソッドはコールされた時点では開始されるだけで、完了していません。 アンロードが完了されるのは、以下の条件を満たしたときです。 コール スタックに、AssemblyLoadContext にロードされたアセンブリ内のメソッドを含むスレッドがなくなった。 AssemblyLoadContext にロードされたアセンブリ内の型、それらの型のインスタンス、およびアセンブリ自体が参照されなくなった。 つまりちゃんと考えて設計をしないと、いつまでたってもアンロードが完了しない事も起こります。 サンプル作成 それでは実際にアセンブリをアンロードする仕組みを実装してみます。 1. ロードされるクラスライブラリを作成 なんでもよいのですが、以下のような簡単なクラスを定義しました。 TargetFrameworkにはnetstandard2.1を指定しています。 これはClassLibrary1.dllという名前で出力されるようにしておきます。 namespace ClassLibrary1 { public class Class1 { public void Hello(int arg) { Console.WriteLine(arg); } } } 2. ロードする側にAssemblyLoadContextを実装 まずはアセンブリを読み込むためのAssemblyLoadContext を作成します。 今回作成したのは以下のような簡単なクラスです。 ...

2019-12-10 · 2 分 · 369 文字 · ayumax