HMD を被らずに確かめる
どちらの方法を使うか
Section titled “どちらの方法を使うか”見た目を確かめるために HMD を被る回数は、デスクトップの窓に出す方法か、画像にして見る方法で減らせます。窓に出す方法は、画面をモニターで見ながらマウスで操作でき、マウスの操作に対する動きも確かめられます。画像にする方法は、ウィジェットを PNG ファイルに書き出すので、SteamVR も HMD も要りません。ただし、書き出すのは描画を1回実行した時点の見た目だけで、動きや操作は確かめられません。
| 方法 | できること | SteamVR と HMD |
|---|---|---|
| 方法1: デスクトップの窓に出す | 画面をモニターで見る。マウスで押す | 起動と接続が要る |
| 方法2: 画像にして比べる | ウィジェットのある時点の見た目を PNG にして、保存した画像を開いて見る。動きと操作は確かめられない | 要らない |
どちらの方法も、HMD の中で動くことの確認の代わりにはなりません。最後は HMD で確かめます。
- 方法1:
DashboardWindowで出している起動のコードがあること - 方法1: SteamVR を起動し、HMD を接続していること
- 方法2: テストしたいウィジェットがあること
- 方法2: プロジェクトに
FloatSoda.Testingパッケージを足していること
方法1でも HMD の接続が要る理由は、FloatSoda が表示先によらず、起動時に OpenVR を初期化するためです。HMD が未接続だと Init_HmdNotFound で起動に失敗します(追跡: #140)。方法1で省けるのは、HMD を頭に付ける手間だけです。
方法1: デスクトップの窓に出す
Section titled “方法1: デスクトップの窓に出す”起動のコードで DashboardWindow を渡している箇所を、DesktopWindow に替えます。DesktopWindow は、開発機のデスクトップ上に見える窓として画面を出します。
var useDesktop = args.Contains("--desktop");var hostArgs = args.Where(argument => argument != "--desktop").ToArray();
var builder = Host.CreateApplicationBuilder(hostArgs);builder.Services.AddFloatSoda();
using var host = builder.Build();var app = host.Services.GetRequiredService<FloatSodaApp>();
app.CreateWindow(useDesktop ? new DesktopWindow { Title = "MyOverlay", Child = root } : new DashboardWindow { Dpm = new Dpm(100), Title = "MyOverlay", Child = root });
await host.RunAsync();Dpm は FloatSoda.Abstractions.Geometries の名前空間にあります。--desktop を付けて起動すると窓に出て、付けないと従来どおりダッシュボードに出ます。--desktop はこのアプリで処理する引数なので、Host.CreateApplicationBuilder に渡す引数から取り除きます。このコードは、GestureDetector のサンプルと同じ形です。
dotnet run -- --desktopできた? デスクトップに窓が出て、マウスで操作できれば、方法1は完了です。
できなかったら
窓が出ない、または起動時に例外が出るときは、エラーを読んで直すで原因を切り分けます。HMD を接続していない場合は、前提条件のとおり Init_HmdNotFound で失敗します。
デスクトップで動いても、ダッシュボードで動く証明にはなりません。ウィンドウの種類ごとに、ポインターの座標が届く仕組みが違うためです(追跡: #182)。ボタンを押せる画面は、最後に HMD のダッシュボードでも確かめます。
方法2: 画像にして比べる
Section titled “方法2: 画像にして比べる”WidgetBitmapRenderer.Render にウィジェットと画像のサイズを渡すと、ビルド、レイアウト、ペイントを1回実行して、結果を SKBitmap で返します。この方法は SteamVR を使いません。
using FloatSoda.Testing;using SkiaSharp;
var renderer = new WidgetBitmapRenderer();
using var bitmap = renderer.Render(root, new SKSizeI(400, 300));using var image = SKImage.FromBitmap(bitmap);using var data = image.Encode(SKEncodedImageFormat.Png, 100);
File.WriteAllBytes("widget.png", data.ToArray());root には、HMD の中に出したい画面のウィジェットを渡します。Render は1回しか実行しないので、Image ウィジェットのように、画像を非同期で読み込む部品は、読み込み前の状態で描かれます。画像まで描きたいときは、Image に渡すものと同じプロバイダーを変数に持ち、Render の前に await provider.ResolveAsync() を実行します。返されたハンドルは、描画が終わるまで手放さないでください。次の例は、using var で、スコープの終わりまでハンドルを保持します。
using FloatSoda.Core.Providers;
var provider = new FileImageProvider("photo.png");Widget imageRoot = new Image { Provider = provider };
using var handle = await provider.ResolveAsync();using var bitmap = renderer.Render(imageRoot, new SKSizeI(400, 300));FloatSoda.Samples.PaintingSample も、ウィジェットのツリーを PNG に書き出します。コードはPaintingSample の Program.csにあります。
画像を期待する画像と自動で比べる方法は、この手順では扱いません。書き出した PNG を開いて、目で見て確かめます。
できた? widget.png が保存され、開くと、400 × 300 ピクセルの画像の中で、配置、色、文字が意図どおりになっていれば、方法2は完了です。HMD の中での実寸と操作は、HMD で別に確かめます。
結果を確かめる
Section titled “結果を確かめる”窓または画像で、次の3点を見ます。
- 配置: 部品が思った場所に、思った大きさで並んでいる
- 色: 背景と文字の色が指定どおりに出ている
- 文字: 文字が切れずに、読める大きさで出ている
HMD の中で最後に確かめる項目は、押せるかどうかと、実寸の大きさです。見た目の指定は見た目を整える、押せる部品はボタンやトグルを組み立てるで扱います。
うまくいかないとき
Section titled “うまくいかないとき”窓が出ない、または起動で例外が出るときは、エラーを読んで直すで原因を切り分けます。