Metaverse Art Gallery
Overview
The Art Galery space is an example on how to use an API to display artworks dynamically.
The player can use the search field and enter any keyword to look for artworks and display them on the gallery walls.
For this, we use the Art Institute of Chicago API to explore and display the public data of the museum.
The Art Institute of Chicago API has been selected for several reasons :
- the API is well documented
- artworks are very qualitative
- CC0 content filtering is possible
ArticDisplay
Artworks placeholders have been dispatched on the walls of the gallery at predefined positions.
In addition to the painting, we also display information about it (title, author, description).
There is also a button to display the real size of the work or a larger size.
Each artworks placeholder is managed by the ArticDisplay
class and all parameters of an artwork are registered in a network structure called 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;
...
}
As soon as an artwork property is changed, the OnArticArtworkChanged()
method is called to update the display.
C#
[Networked(OnChanged = nameof(OnArticArtworkChanged))]
public ArticArtwork articArtwork { get; set; }
static void OnArticArtworkChanged(Changed<ArticDisplay> changed)
{
changed.Behaviour.OnArticArtworkChanged();
}
private void OnArticArtworkChanged()
{
if (articArtwork.isVisible)
DisplayArtWork();
else
HideArtWork();
}
SearchManager
A search panel is placed at the entrance of the gallery.
To make it easier to use, some buttons for predefined searches have been added.
When the player touchs one of this predefined button, the SearchManager LaunchPredefinedSearch()
method is called with the predefined word in parameter.
If the user enters any keyword with the keyboard and use the Search button, then it calls the LaunchSearch()
method.
Please note that the search keyword is synchronized on the network : this is usefull for the UI but also to avoid resources consumption (bandwidth and API) if the same search is performed by two users.
C#
[Networked(OnChanged = nameof(OnKeywordChanged))]
public NetworkString<_128> keyword { get; set; }
static void OnKeywordChanged(Changed<SearchManager> changed)
{
changed.Behaviour.OnKeywordChanged();
}
private void OnKeywordChanged()
{
keywordInputField.Text= keyword.ToString();
}
When a search is initiated (asynchronous DoLaunchSearch()
task), first it requests the StateAuthority
and synchronizes the search keyword for remote players.
Then, it asks the ArticGalleryManager
to search for the string passed in parameter.
This way, it means that only one player performs the search even if all players see the searched keyword.
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
is in charge to search items into the Art Institute of Chicago library using a keyword and to display the results on the artwork places holders.
To do so, a list of all ArticDisplay
in the scene is initialized during the Awake()
.
During the LaunchSearch
task, it uses the ArticSearchRequest
method to find approriate artworks.
Results are recorded into an artworkDescriptions
list and displayed thanks to FillDisplayFound()
& FillDisplayAsync()
functions :
FindMostFittingDisplay()
is in charge to find a suitable artworks place holder (some walls can accommodate larger artworks than others).FillDisplayAsync()
updates the artwork properties with the data received from the API, requests theStateAuthority
on the artwork place holder and synchronize it over the network.
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
The ArticAPIManager
class manages the Art Institute of Chicago API.
There is no dependency on Fusion SDK.
The API documentation is available here