Use case : Getting Workspace and Scene information
This guide explains how to set up your scene in order to get workspace and scene information.
Prerequisites
- Follow Identity's Integrating authentication in your scene guide.
Overview
In order to retrieve workspace and scene information, perform the following procedures:
- Instantiate a WorkspaceProvider in PlatformServices
- Write the SceneManager class to handle selection of workspaces and scenes
- Display workspace and scene information in the screen (optional)
Instantiate a WorkspaceProvider in PlatformServices
In the PlatformServices class, add a public reference to
IWorkspaceProvider
, and a private reference to theWorkspaceProvider
implementation.static WorkspaceProvider s_WorkspaceProvider; public static IWorkspaceProvider WorkspaceProvider => s_WorkspaceProvider;
Initialize the services properly in the InitializeAsync method. The variable provided in the constructor have been defined in Identity's Getting user information guide.
public static async Task InitializeAsync() { // ... s_WorkspaceProvider = new WorkspaceProvider(s_ServiceHttpClient, s_CloudConfiguration); // ... }
Shutdown the services properly in the Shutdown method.
public static void ShutDownServices() { // ... s_WorkspaceProvider = null; // ... }
Write the SceneManager class to handle selection of workspaces and scenes
In your scene, create two dropdowns, whose purpose is to select a worskpace and a scene.
Create a new
SceneManager
script, and attach it to theSceneManager
GameObject. This script will be responsible of managing workspace and scene have been selected by the user.The
SceneManager
class should contain :- References to the dropdowns
- References to
IAuthenticator
andIWorkspaceProvider
services - References to the lists of Workspaces and Scenes
Two events that get raised whenever the user selects a different workspace or scene
public class SceneManager : MonoBehaviour { [SerializeField] Dropdown m_WorkspaceDropdown; [SerializeField] Dropdown m_SceneDropdown; IAuthenticator m_Authenticator; IWorkspaceProvider m_WorkspaceProvider; List<IWorkspace> m_Workspaces; List<IScene> m_Scenes; public event Action<IWorkspace> WorkspaceSelected; public event Action<IScene> SceneSelected; }
Next, the Awake method should retrieve the services from PlatformServices. Then, it can subscribe to different events (which need to be unsubscribed in OnDestroy).
void Awake() { m_Authenticator = PlatformServices.InteractiveAuthenticator; m_WorkspaceProvider = PlatformServices.WorkspaceProvider; m_Authenticator.AuthenticationStateChanged += OnAuthenticationStateChanged; m_WorkspaceDropdown.onValueChanged.AddListener(new UnityEngine.Events.UnityAction<int>(ApplyWorkspaceUpdate)); m_SceneDropdown.onValueChanged.AddListener(new UnityEngine.Events.UnityAction<int>(ApplySceneUpdate)); } void OnDestroy() { m_Authenticator.AuthenticationStateChanged -= OnAuthenticationStateChanged; m_WorkspaceDropdown.onValueChanged.RemoveAllListeners(); m_SceneDropdown.onValueChanged.RemoveAllListeners(); }
Then, we implement the OnAuthenticationStateChanged method : if the user is logged out, we empty the workspaces and send null to both events. Otherwise, we'll start by populating the workspaces.
async void OnAuthenticationStateChanged(AuthenticationState state) { if (state == AuthenticationState.LoggedIn) { await PopulateWorkspaces(); } else { m_WorkspaceDropdown.ClearOptions(); m_SceneDropdown.ClearOptions(); m_WorkspaceDropdown.interactable = false; m_SceneDropdown.interactable = false; WorkspaceSelected?.Invoke(null); SceneSelected?.Invoke(null); } }
Implement the PopulateWorkspaces method. We simply need to iterate over the available workspaces (thanks to the
IWorkspaceProvider
) and fill the dropdown with their different names. Based on the number of available workspaces, we make the dropdown interactable or not. We also callApplyWorkspaceUpdate
to update the UI instantly.async Task PopulateWorkspaces() { m_WorkspaceDropdown.ClearOptions(); var list = new List<Dropdown.OptionData>(); m_Workspaces = (await m_WorkspaceProvider.ListWorkspacesAsync()).ToList(); foreach (var workspace in m_Workspaces) { list.Add(new Dropdown.OptionData(workspace.Name)); } if (list.Count > 0) { m_WorkspaceDropdown.AddOptions(list); m_WorkspaceDropdown.interactable = true; ApplyWorkspaceUpdate(m_WorkspaceDropdown.value); } else { m_WorkspaceDropdown.interactable = false; WorkspaceSelected?.Invoke(null); } }
The
ApplyWorkspaceUpdate
method raises the WorkspaceSelected event, and launches thePopulateScenes
process.async void ApplyWorkspaceUpdate(int value) { var workspace = m_Workspaces[value]; WorkspaceSelected?.Invoke(workspace); await PopulateScenes(workspace); }
Implement the PopulateScene method, which is very similar to PopulateWorkspace. The only difference is that we need an
IWorkspace
argument to call itsListScenesAsync
method.async Task PopulateScenes(IWorkspace workspace) { m_SceneDropdown.ClearOptions(); var list = new List<Dropdown.OptionData>(); m_Scenes = (await workspace.ListScenesAsync()).ToList(); foreach (var scene in m_Scenes) { list.Add(new Dropdown.OptionData(scene.Name)); } if (list.Count > 0) { m_SceneDropdown.AddOptions(list); m_SceneDropdown.interactable = true; ApplySceneUpdate(m_SceneDropdown.value); } else { m_SceneDropdown.interactable = false; SceneSelected?.Invoke(null); } }
The
ApplySceneUpdate
method raises the SceneSelected event.void ApplySceneUpdate(int value) { var scene = m_Scenes[value]; SceneSelected?.Invoke(scene); }
Display workspace and scene information in the screen (optional)
In your scene, create two (large) Text fields, whose purpose is to display information about the selected worskpace and scene.
Create a new
SceneInfoUpdater
script, and attach it to theSceneManager
GameObject. This script will be responsible hooking to the workspace and scene selected events, and updating the text to show information.The
SceneInfoUpdater
class should contain :- References to the text fields
A reference to the
SceneManager
created abovepublic class SceneInfoUpdater : MonoBehaviour { [SerializeField] SceneManager m_SceneManager; [SerializeField] Text m_WorkspaceText; [SerializeField] Text m_SceneText; }
Next, the Awake method should simply subscribe to
SceneManager
's events ; similarly, the OnDestroy method should unsubcribe.void Awake() { m_SceneManager.WorkspaceSelected += OnWorkspaceSelected; m_SceneManager.SceneSelected += OnSceneSelected; } void OnDestroy() { m_SceneManager.WorkspaceSelected -= OnWorkspaceSelected; m_SceneManager.SceneSelected -= OnSceneSelected; }
Finally, we can implement
OnWorkspaceSelected
andOnSceneSelected
to update the info accordingly.void OnWorkspaceSelected(IWorkspace workspace) { m_WorkspaceText.text = workspace == null ? "No workspace selected" : workspace.Id.ToString(); } void OnSceneSelected(IScene scene) { m_SceneText.text = scene == null ? "No scene selected" : scene.Id.ToString(); }