docs.unity3d.com
    Show / Hide Table of Contents

    Get started with Asset Discovery

    Asset Discovery is a Unity Cloud service that allows you to discover and manage your project's published assets. You can use Asset Discovery to:

    • Get a published asset
    • Search for published assets based on a set of criteria
    • Aggregate published assets based on a set of criteria

    This section explains how to set up a basic scene and script to initialize and use the Unity Asset Manager SDK package with Asset Discovery. It performs a basic search for published assets of the selected project and displays the results in a simple GUI.

    Requirements

    To use Asset Discovery, you must have a minimum role of:

    • Manager in the Unity Cloud Organization you belong to.
      OR
    • Asset Manager Viewer in the Unity Cloud Project you belong to.

    Configure the package

    To configure the Unity Asset Manager SDK package, you must do the following:

    • Set up a Unity scene
    • Create an AssetDiscovery
    • Create the PlatformServices

    Set up a Unity scene

    To set up a Unity scene, perform the following steps:

    1. In your Unity project window, navigate to Assets > Scenes.
    2. Right-click the Assets/Scenes folder and navigate to Create > Scene.
    3. Name the new scene AssetDiscoveryExample.

    Create an AssetDiscovery

    To create a MonoBehaviour, perform the following steps:

    1. In your Unity project window, go to Assets > Scripts. Create an Assets/Scripts folder if the folder doesn't already exist.
    2. Right-click the Assets/Scripts folder and go to Create > C# Script. Name your script AssetDiscoveryUI.
    3. In the AssetDiscoveryExample scene you created earlier, right-click the hierarchy and select Create Empty.
    4. Name your new object AssetDiscovery.
    5. Select the AssetDiscovery object and add the AssetDiscoveryUI script you created earlier.

    Create the PlatformServices

    To instantiate the necessary providers and managers, follow these steps:

    1. Implement the platform services pattern. See the Best practices: dependency injection page of the Identity package documentation for more information.
    2. Update the PlatformServices class in your PlatformServices.cs file to look like the following:
    
    using System;
    using System.Threading.Tasks;
    using Unity.Cloud.Assets;
    using Unity.Cloud.Common;
    using Unity.Cloud.Common.Runtime;
    using Unity.Cloud.Identity;
    using Unity.Cloud.Identity.Runtime;
    
    public static class PlatformServices
    {
        /// <summary>
        /// Returns a <see cref="ICompositeAuthenticator"/>.
        /// </summary>
        public static ICompositeAuthenticator Authenticator { get; private set; }
    
        /// <summary>
        /// Returns a <see cref="IAuthenticationStateProvider"/>.
        /// </summary>
        public static IAuthenticationStateProvider AuthenticationStateProvider => Authenticator;
    
        /// <summary>
        /// Returns an <see cref="IOrganizationProvider"/>.
        /// </summary>
        public static IOrganizationProvider OrganizationProvider { get; private set; }
    
        /// <summary>
        /// Returns an <see cref="IProjectProvider"/>.
        /// </summary>
        public static IProjectProvider ProjectProvider { get; private set; }
    
        /// <summary>
        /// Returns an <see cref="IAssetProvider"/>
        /// </summary>
        public static IAssetProvider AssetProvider { get; private set; }
    
        public static void Create()
        {
            var httpClient = new UnityHttpClient();
            var serviceHostResolver = UnityRuntimeServiceHostResolverFactory.Create();
            var playerSettings = UnityCloudPlayerSettings.Instance;
            var platformSupport = PlatformSupportFactory.GetAuthenticationPlatformSupport();
    
            var compositeAuthenticatorSettings = new CompositeAuthenticatorSettingsBuilder(httpClient, platformSupport, serviceHostResolver)
                .AddDefaultPkceAuthenticator(playerSettings)
                .Build();
    
            Authenticator = new CompositeAuthenticator(compositeAuthenticatorSettings);
    
            var serviceHttpClient = new ServiceHttpClient(httpClient, Authenticator, playerSettings);
    
            OrganizationProvider = new CloudOrganizationProvider(serviceHttpClient, serviceHostResolver);
            ProjectProvider = new CloudProjectProvider(serviceHttpClient, serviceHostResolver);
    
            var assetServiceConfiguration = new AssetServiceConfiguration(true);
    
            AssetProvider = new CloudAssetProvider(serviceHttpClient, serviceHostResolver, assetServiceConfiguration);
        }
    
        /// <summary>
        /// A Task that initializes all platform services.
        /// </summary>
        /// <returns>A Task.</returns>
        public static async Task InitializeAsync()
        {
            await Authenticator.InitializeAsync();
        }
    
        /// <summary>
        /// Shuts down all platform services.
        /// </summary>
        public static void ShutDownServices()
        {
            (Authenticator as IDisposable)?.Dispose();
            Authenticator = null;
        }
    }
    
    

    What this script accomplishes:

    • Initializes an IAuthenticator for logging in and verifying your identity when accessing the HTTP services.
    • Initializes an IOrganizationProvider to fetch the organizations you belong to.
    • Initializes an IProjectProvider to fetch the projects you have access to.
    • Initializes an IAssetProvider to fetch your assets.

    To initialize the PlatformServices in your scene, follow these steps:

    1. In your Unity project window, go to Assets > Scripts.
    2. Right-click the Assets/Scripts folder and go to Create > C# Script. Name your script PlatformServicesInitialization.
    3. In the AssetDiscoveryExample scene you created earlier, right-click the hierarchy and select Create Empty.
    4. Name your new object PlatformServices.
    5. Select the PlatformServices object and add the PlatformServicesInitialization script you created earlier.
    6. Update the PlatformServicesInitialization class in your PlatformServicesInitialization.cs file to look like the following:
    
    using System.Threading.Tasks;
    using UnityEngine;
    
    /// <summary>
    /// A Mono behaviour class to initialize services and dependencies for the Unity Cloud platform.
    /// </summary>
    [DefaultExecutionOrder(int.MinValue)]
    [AddComponentMenu("Assets/Manual/Discovery/Platform Services Initialization")]
    public class PlatformServicesInitialization : MonoBehaviour
    {
        void Awake()
        {
            DontDestroyOnLoad(gameObject);
            PlatformServices.Create();
        }
    
        async Task Start()
        {
            await PlatformServices.InitializeAsync();
        }
    }
    
    

    What this script accomplishes:

    • Triggers the creation of the services available in the PlatformServices.
    • Initializes the IAuthenticator.

    To clean up the PlatformServices in your scene, follow these steps:

    1. In your Unity project window, go to Assets > Scripts.
    2. Right-click the Assets/Scripts folder and go to Create > C# Script. Name your script PlatformServicesShutdown.
    3. Select the PlatformServices object you created earlier and add the PlatformServicesShutdown script you created earlier.
    4. Update the PlatformServicesShutdown class in your PlatformServicesShutdown.cs file to look like the following:
    
    using UnityEngine;
    
    /// <summary>
    /// A Mono behaviour class to shut down services and dependencies from the Unity Cloud platform.
    /// </summary>
    [DefaultExecutionOrder(int.MaxValue)]
    [AddComponentMenu("Assets/Manual/Discovery/Platform Services Shutdown")]
    public class PlatformServicesShutdown : MonoBehaviour
    {
        void OnDestroy()
        {
            PlatformServices.ShutDownServices();
        }
    }
    
    

    This script cleans up of the services when the scene is closed.

    Create the behaviour for getting assets

    To create the behaviour for asset discovery, perform the following steps:

    1. In your Unity project window, go to Assets > Scripts.
    2. Right-click the Assets/Scripts folder and go to Create > C# Script. Name your script AssetDiscoveryBehaviour.
    3. Open the AssetDiscoveryBehaviour script you created and replace the contents of the file with the following code sample:
    
    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Unity.Cloud.Assets;
    using UnityEngine;
    
    public class AssetDiscoveryBehaviour
    {
        static readonly Pagination m_DefaultPagination = new(nameof(IAsset.Name), Range.All);
    
        IOrganization[] m_AvailableOrganizations;
        IOrganization m_CurrentOrganization;
    
        CancellationTokenSource m_ProjectCancellationTokenSrc = new();
        CancellationTokenSource m_AssetCancellationTokenSrc = new();
    
        public IOrganization[] AvailableOrganizations => m_AvailableOrganizations;
        public IOrganization CurrentOrganization => m_CurrentOrganization;
        public bool IsOrganizationSelected => m_CurrentOrganization != null;
        public List<IProject> AvailableProjects { get; } = new();
        public IProject CurrentProject { get; private set; }
        public bool IsProjectSelected => CurrentProject != null;
        public List<IAsset> AvailableAssets { get; } = new();
        public IAsset CurrentAsset { get; set; }
    
        public void Clear()
        {
            m_ProjectCancellationTokenSrc.Cancel();
            m_ProjectCancellationTokenSrc.Dispose();
            m_AssetCancellationTokenSrc.Cancel();
            m_AssetCancellationTokenSrc.Dispose();
    
            CurrentAsset = null;
            CurrentProject = null;
            m_CurrentOrganization = null;
        }
    
        public void SetSelectedOrganization(IOrganization organization)
        {
            m_CurrentOrganization = organization;
            if (m_CurrentOrganization != null)
            {
                GetProjects();
            }
        }
    
        public void SetSelectedProject(IProject project)
        {
            CurrentProject = project;
            if (CurrentProject != null)
            {
                GetAssets();
            }
        }
    
        public async Task GetOrganizationsAsync()
        {
            m_AvailableOrganizations = null;
    
            try
            {
                var cancellationTokenSrc = new CancellationTokenSource();
                m_AvailableOrganizations = await PlatformServices.OrganizationProvider.GetOrganizationsAsync(cancellationTokenSrc.Token);
            }
            catch (OperationCanceledException oe)
            {
                Debug.LogError(oe);
            }
            catch (AggregateException e)
            {
                Debug.LogError(e.InnerException);
            }
            catch (Exception e)
            {
                Debug.LogError(e);
            }
        }
    
        public void GetProjects()
        {
            m_ProjectCancellationTokenSrc.Cancel();
            m_ProjectCancellationTokenSrc.Dispose();
            m_ProjectCancellationTokenSrc = new CancellationTokenSource();
    
            try
            {
                var projects = PlatformServices.ProjectProvider.ListProjectsAsync(m_CurrentOrganization, m_DefaultPagination, m_ProjectCancellationTokenSrc.Token);
                _ = PopulateProjectsAsync(projects);
            }
            catch (OperationCanceledException oe)
            {
                Debug.LogError(oe);
            }
            catch (AggregateException e)
            {
                Debug.LogError(e.InnerException);
            }
            catch (Exception e)
            {
                Debug.LogError(e);
            }
        }
    
        async Task PopulateProjectsAsync(IAsyncEnumerable<IProject> projects)
        {
            AvailableProjects.Clear();
            CurrentProject = null;
    
            await foreach (var project in projects.WithCancellation(m_ProjectCancellationTokenSrc.Token))
            {
                AvailableProjects.Add(project);
            }
        }
    
        void GetAssets()
        {
            m_AssetCancellationTokenSrc.Cancel();
            m_AssetCancellationTokenSrc.Dispose();
            m_AssetCancellationTokenSrc = new CancellationTokenSource();
    
            try
            {
                var assets = PlatformServices.AssetProvider.SearchAsync(new AssetSearchFilter(CurrentProject), m_DefaultPagination, m_AssetCancellationTokenSrc.Token);
                _ = PopulateAssetsAsync(assets);
            }
            catch (OperationCanceledException oe)
            {
                Debug.LogError(oe);
            }
            catch (AggregateException e)
            {
                Debug.LogError(e.InnerException);
            }
            catch (Exception e)
            {
                Debug.LogError(e);
            }
        }
    
        async Task PopulateAssetsAsync(IAsyncEnumerable<IAsset> assets)
        {
            AvailableAssets.Clear();
            CurrentAsset = null;
    
            await foreach (var asset in assets.WithCancellation(m_AssetCancellationTokenSrc.Token))
            {
                AvailableAssets.Add(asset);
            }
        }
    }
    
    

    The script does the following:

    • Provides the functions to list and select organizations.
    • Provides the functions to list and select projects.
    • Performs a basic search to list the published assets of the selected project.

    Create the UI for navigating assets

    To create a simple UI for navigating assets, do the following: Open the AssetDiscoveryUI script you created earlier and replace the contents of the file with the following code sample:

    
    using System;
    using Unity.Cloud.Identity;
    using UnityEngine;
    
    public class AssetDiscoveryUI : MonoBehaviour
    {
        protected readonly AssetDiscoveryBehaviour m_Behaviour = new();
        IAuthenticationStateProvider m_AuthenticationStateProvider;
    
        Vector2 m_ProjectListScrollPosition;
        Vector2 m_AssetListScrollPosition;
    
        bool IsLoggedIn => m_AuthenticationStateProvider?.AuthenticationState == AuthenticationState.LoggedIn;
    
        void Start()
        {
            m_AuthenticationStateProvider = PlatformServices.AuthenticationStateProvider;
            m_AuthenticationStateProvider.AuthenticationStateChanged += OnAuthenticationStateChanged;
        }
    
        void OnDestroy()
        {
            if (m_AuthenticationStateProvider != null)
            {
                m_AuthenticationStateProvider.AuthenticationStateChanged -= OnAuthenticationStateChanged;
            }
        }
    
        void OnGUI()
        {
            GUILayout.BeginHorizontal();
    
            UpdateAuthenticationUI(m_AuthenticationStateProvider.AuthenticationState);
    
            if (!IsLoggedIn)
            {
                GUILayout.EndHorizontal();
                return;
            }
    
            if (!m_Behaviour.IsOrganizationSelected)
            {
                // Refresh the org list
                if (GUILayout.Button("Refresh"))
                {
                    _ = m_Behaviour.GetOrganizationsAsync();
                    return;
                }
    
                GUILayout.Space(50);
    
                // If an organization is not selected, list those available.
                SelectAnOrganization();
            }
            else if (!m_Behaviour.IsProjectSelected)
            {
                GUILayout.BeginVertical();
    
                // Go back to select a different scene.
                if (GUILayout.Button("Back"))
                {
                    m_Behaviour.SetSelectedOrganization(null);
                    return;
                }
    
                // Refresh the org list
                if (GUILayout.Button("Refresh"))
                {
                    m_Behaviour.GetProjects();
                    return;
                }
    
                GUILayout.EndVertical();
    
                GUILayout.Space(50);
    
                SelectAProject();
            }
            else
            {
                // Go back to select a different scene.
                if (GUILayout.Button("Back"))
                {
                    m_Behaviour.SetSelectedProject(null);
                    return;
                }
    
                GUILayout.Space(50);
    
                SelectAnAsset();
    
                GUILayout.Space(50);
    
                AssetActions();
            }
    
            GUILayout.EndHorizontal();
        }
    
        protected virtual void AssetActions()
        {
            // Add additional actions here.
        }
    
        void SelectAnOrganization()
        {
            GUILayout.BeginVertical();
    
            GUILayout.Label("Available Organizations:");
            GUILayout.Space(10);
    
            var availableOrganizations = m_Behaviour.AvailableOrganizations;
            if (availableOrganizations != null)
            {
                for (var i = 0; i < availableOrganizations.Length; ++i)
                {
                    if (GUILayout.Button(availableOrganizations[i].Name))
                    {
                        m_Behaviour.SetSelectedOrganization(availableOrganizations[i]);
                    }
                }
            }
            else
            {
                GUILayout.Label("Loading...");
            }
    
            GUILayout.EndVertical();
        }
    
        void SelectAProject()
        {
            GUILayout.BeginVertical();
    
            GUILayout.Label($"{m_Behaviour.CurrentOrganization.Name}");
            GUILayout.Space(10);
    
            GUILayout.Label("Available Projects:");
            GUILayout.Space(10);
    
            var projects = m_Behaviour.AvailableProjects;
            if (projects.Count > 0)
            {
                m_ProjectListScrollPosition = GUILayout.BeginScrollView(m_ProjectListScrollPosition, GUILayout.Height(Screen.height * 0.8f));
    
                for (var i = 0; i < projects.Count; ++i)
                {
                    if (GUILayout.Button(projects[i].Name))
                    {
                        m_Behaviour.SetSelectedProject(projects[i]);
                    }
                }
    
                GUILayout.EndScrollView();
            }
            else
            {
                GUILayout.Label("No projects found.");
            }
    
            GUILayout.EndVertical();
        }
    
        void SelectAnAsset()
        {
            GUILayout.BeginVertical();
    
            GUILayout.Label($"{m_Behaviour.CurrentOrganization.Name} >> {m_Behaviour.CurrentProject.Name}");
            GUILayout.Space(10);
    
            GUILayout.Label("Available Assets:");
            GUILayout.Space(10);
    
            var assets = m_Behaviour.AvailableAssets;
            if (assets.Count > 0)
            {
                m_AssetListScrollPosition = GUILayout.BeginScrollView(m_AssetListScrollPosition, GUILayout.Height(Screen.height * 0.3f));
    
                for (var i = 0; i < assets.Count; ++i)
                {
                    if (GUILayout.Button(assets[i].Name))
                    {
                        m_Behaviour.CurrentAsset = assets[i];
                        Debug.Log($"Selected: {assets[i].Name}");
                    }
                }
    
                GUILayout.EndScrollView();
            }
            else
            {
                GUILayout.Label("No assets found.");
            }
    
            GUILayout.EndVertical();
        }
    
        static void UpdateAuthenticationUI(AuthenticationState state)
        {
            GUILayout.BeginVertical();
    
            switch (state)
            {
                case AuthenticationState.AwaitingInitialization:
                    GUILayout.Label("Initializing Service...");
                    break;
    
                case AuthenticationState.AwaitingLogout:
                    GUILayout.Label("Logging out...");
                    break;
    
                case AuthenticationState.LoggedOut:
                    if (GUILayout.Button("Login"))
                    {
                        _ = PlatformServices.Authenticator.LoginAsync();
                    }
    
                    break;
    
                case AuthenticationState.AwaitingLogin:
                    GUILayout.Label("Logging in...");
                    if (GUILayout.Button("Cancel"))
                    {
                        PlatformServices.Authenticator.CancelLogin();
                    }
    
                    break;
    
                case AuthenticationState.LoggedIn:
                    if (GUILayout.Button("Logout"))
                    {
                        _ = PlatformServices.Authenticator.LogoutAsync();
                    }
    
                    break;
    
                default:
                    throw new ArgumentOutOfRangeException(nameof(state), state, null);
            }
    
            GUILayout.EndVertical();
        }
    
        void OnAuthenticationStateChanged(AuthenticationState obj)
        {
            if (obj == AuthenticationState.LoggedIn)
            {
                _ = m_Behaviour.GetOrganizationsAsync();
            }
        }
    }
    
    

    The script does the following:

    • Registers to the IAuthenticator to track login changes.
    • Creates an instance of an AssetDiscoveryBehaviour.
    • Creates a simple UI flow for selecting organizations, projects and assets.
    Back to top
    Copyright © 2023 Unity Technologies — Terms of use
    • Legal
    • Privacy Policy
    • Cookies
    • Do Not Sell or Share My Personal Information
    • Your Privacy Choices (Cookie Settings)
    "Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
    Generated by DocFX on 18 October 2023