Metaverse Art Gallery
概要
Art Galleryスペースは、アートワークを動的に表示するAPIを使用する方法の例になります。
プレイヤーは、検索フィールドにキーワードを入力してアートワークを探して、ギャラリーの壁にそれらを表示できます。
このために、ミュージアムの公開データを調べて表示するためのArt Institute of Chicago APIを使用しています。
Art Institute of Chicago APIを選択した理由は以下の通りです。
- APIのドキュメントが整備されている
- アートワークは非常に品質が高い
- CC0のコンテンツのフィルタリングが可能
ArticDisplay
アートワークのプレースホルダーは、ギャラリーの壁の定義済みの位置に送られます。
絵画に加えて、その絵画の情報(タイトル、画家名、説明)も表示します。
また、絵画を実物のサイズか大きいサイズで表示するボタンも存在します。
各アートワークのプレースホルダーは、ArticDisplay
クラスで管理され、アートワークのすべてのパラメーターは、ArticArtwork
と呼ばれるネットワーク構造体に保持されます。
C#
public struct ArticArtwork : INetworkStruct
{
public NetworkBool isVisible;
public int id;
public NetworkString<_64> image_id;
public NetworkString<_128> title;
public NetworkString<_128> artist_display;
public Vector2 dimension;
...
}
Render()
でChangeDetector
をチェックしているため、アートワークのプロパティが変更されるとすぐにOnArticArtworkChanged()
メソッドが呼ばれ、表示が更新されます。
C#
[Networked]
public ArticArtwork articArtwork { get; set; }
ChangeDetector changeDetector;
public override void Render()
{
base.Render();
foreach (var changedVar in changeDetector.DetectChanges(this))
{
...
if (changedVar == nameof(articArtwork))
{
OnArticArtworkChanged();
}
}
}
private void OnArticArtworkChanged()
{
if (articArtwork.isVisible)
DisplayArtWork();
else
HideArtWork();
}
SearchManager
ギャラリーの入り口には検索パネルが置かれています。
簡単に使えるように、定義済みの検索ボタンが追加されています。
プレイヤーが定義済みボタンの一つをタッチすると、SearchManager
のLaunchPredefinedSearch()
メソッドが呼ばれて、パラメーターに定義済みの単語が渡されます。
ユーザーがキーボードからキーワードを入力して検索ボタンを使用すると、LaunchSearch()
メソッドが呼ばれます。
検索キーワードはネットワーク上で同期されることに注意してください。これはUI表示だけでなく、2人のユーザーが同じ検索を行った時のリソース消費(帯域幅とAPI)の回避に便利です。
C#
[Networked]
public NetworkString<_128> keyword { get; set; }
ChangeDetector changeDetector;
public override void Render()
{
base.Render();
foreach (var changedVar in changeDetector.DetectChanges(this))
{
if (changedVar == nameof(keyword))
{
OnKeywordChanged();
}
}
}
private void OnKeywordChanged()
{
keywordInputField.Text= keyword.ToString();
}
検索を開始する(非同期のDoLaunchSearch()
タスク)と、最初に状態権限をリクエストして、検索キーワードを他のプレイヤーと同期します。
それから、パラメーターに渡された文字列を検索するようにArticGalleryManager
に問い合わせます。
この方法によって、検索キーワードはすべてのプレイヤーに見えますが、検索を行うのは1人のプレイヤーのみになります。
C#
public async Task DoLaunchSearch()
{
await PrepareSearch();
articGalleryManager.LaunchSearch(keyword.ToString());
}
public async Task PrepareSearch()
{
if (Object.StateAuthority != Runner.LocalPlayer)
{
if (!await Object.WaitForStateAuthority()) return;
}
// sync the keyword
keyword = keywordInputField.Text.Trim();
...
}
ArticGalleryManager
ArticGalleryManager
は、キーワードを使用したArt Institute of Chicagoライブラリの検索を担い、アートワークのプレースホルダーに結果を表示します。
そのため、シーンのすべてのArticDisplay
のリストはAwake()
で初期化されます。
LaunchSearch
タスク中に、適切なアートワークを見つけるためArticSearchRequest
メソッドを使用します。
結果はartworkDescriptions
リストに記録され、FillDisplayFound()
とFillDisplayAsync()
関数によって表示されます。
FindMostFittingDisplay()
は、適切なアートワークのプレースホルダーを探します(他より大きなアートワークを収容できる壁があります)FillDisplayAsync()
は、APIからデータを受け取り、アートワークのプレースホルダーの状態権限をリクエストし、ネットワーク上で同期することで、アートワークのプロパティを更新します
C#
async Task FillDisplayAsync(ArticData data, ArticDisplay display, string iiif_url)
{
ArticArtwork articArtWorkTemp = new ArticArtwork();
articArtWorkTemp.isVisible = true;
articArtWorkTemp.title = data.title;
articArtWorkTemp.artist_display = data.artist_display;
articArtWorkTemp.id = data.id;
articArtWorkTemp.image_id = data.image_id;
articArtWorkTemp.dimension = data.ParsedDimensions;
// GET authority on the ArticDisplay
if (display.Object.StateAuthority != display.Runner.LocalPlayer)
{
if (!await display.Object.WaitForStateAuthority()) return;
}
...
// sync the artwork
display.articArtwork = articArtWorkTemp;
...
}
ArticAPIManager
ArticAPIManager
クラスは、Art Institute of Chicago APIを管理します。
これはFusion SDKに依存しません。
APIのドキュメントはこちらをご覧ください。