This document is about: FUSION 2
SWITCH TO

Metaverse Art Gallery


Available in the Industries Circle
Circle

概要

Art Galleryスペースは、アートワークを動的に表示するAPIを使用する方法の例になります。
プレイヤーは、検索フィールドにキーワードを入力してアートワークを探して、ギャラリーの壁にそれらを表示できます。
このために、ミュージアムの公開データを調べて表示するためのArt Institute of Chicago APIを使用しています。

Art Institute of Chicago APIを選択した理由は以下の通りです。

  • APIのドキュメントが整備されている
  • アートワークは非常に品質が高い
  • CC0のコンテンツのフィルタリングが可能
Fusion Metaverse Art Gallery

ArticDisplay

アートワークのプレースホルダーは、ギャラリーの壁の定義済みの位置に送られます。
絵画に加えて、その絵画の情報(タイトル、画家名、説明)も表示します。
また、絵画を実物のサイズか大きいサイズで表示するボタンも存在します。

Fusion Metaverse Art Gallery

各アートワークのプレースホルダーは、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

ギャラリーの入り口には検索パネルが置かれています。
簡単に使えるように、定義済みの検索ボタンが追加されています。

Fusion Metaverse Art Gallery

プレイヤーが定義済みボタンの一つをタッチすると、SearchManagerLaunchPredefinedSearch()メソッドが呼ばれて、パラメーターに定義済みの単語が渡されます。
ユーザーがキーボードからキーワードを入力して検索ボタンを使用すると、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のドキュメントはこちらをご覧ください。

Back to top