docs.unity3d.com
    Show / Hide Table of Contents

    Get started with Asset Management

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

    • Get an asset
    • Search for assets
    • Aggregate assets based on a set of criteria
    • Create, read, update, and delete assets

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

    Requirements

    To use Asset Management and manage assets, 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 AssetManager
    • 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 AssetManagementExample.

    Create an AssetManager

    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 AssetManagementUI.
    3. In the AssetManagementExample scene you created earlier, right-click the hierarchy and select Create Empty.
    4. Name your new object AssetManager.
    5. Select the AssetManager object and add the AssetManagementUI script you created earlier.

    Create the PlatformServices

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

    1. Implement the platform services pattern. See Best practices: dependency injection 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="IAssetManager"/>
        /// </summary>
        public static IAssetManager AssetManager { get; private set; }
    
        /// <summary>
        /// Returns an <see cref="IAssetFileManager"/>
        /// </summary>
        public static IAssetFileManager AssetFileManager { get; private set; }
    
        /// <summary>
        /// Returns an <see cref="IAssetCollectionManager"/>
        /// </summary>
        public static IAssetCollectionManager AssetCollectionManager { 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);
            AssetManager = new CloudAssetManager(serviceHttpClient, serviceHostResolver);
            AssetFileManager = new CloudAssetFileManager(serviceHttpClient, serviceHostResolver);
            AssetCollectionManager = new CloudAssetCollectionManager(serviceHttpClient, serviceHostResolver);
        }
    
        /// <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 IAssetManager to fetch and manage your assets; also acts as an IAssetProvider.

    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 AssetManagementExample 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/Management/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/Management/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 managing assets

    To create the behaviour for asset management, 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 AssetManagementBehaviour.
    3. Open the AssetManagementBehaviour script you created and replace the contents of the file with the following code sample:
    
    using System;
    using System.Threading;
    using System.Threading.Tasks;
    using UnityEngine;
    
    public class AssetManagementBehaviour
    {
        static readonly Pagination m_DefaultPagination = new(nameof(IAsset.Name), 25);
        const int k_DefaultCancellationTimeout = 5000;
    
        IOrganization[] m_AvailableOrganizations;
        IOrganization m_CurrentOrganization;
    
        IProjectPage m_AvailableProjects;
        IProject m_CurrentProject;
    
        IAssetPage m_AvailableAssets;
    
        public IOrganization[] AvailableOrganizations => m_AvailableOrganizations;
        public IOrganization CurrentOrganization => m_CurrentOrganization;
        public bool IsOrganizationSelected => m_CurrentOrganization != null;
        public IProjectPage AvailableProjects => m_AvailableProjects;
        public IProject CurrentProject => m_CurrentProject;
        public bool IsProjectSelected => m_CurrentProject != null;
        public IAssetPage AvailableAssets => m_AvailableAssets;
        public IAsset CurrentAsset { get; set; }
    
        public void Clear()
        {
            m_CurrentProject = null;
            m_AvailableProjects = null;
            m_CurrentOrganization = null;
        }
    
        public void SetSelectedOrganization(IOrganization organization)
        {
            m_CurrentOrganization = organization;
            if (m_CurrentOrganization != null)
            {
                _ = GetProjectsAsync();
            }
        }
    
        public void SetSelectedProject(IProject project)
        {
            m_CurrentProject = project;
            if (m_CurrentProject != null)
            {
                _ = GetAssetsAsync();
            }
        }
    
        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 async Task GetProjectsAsync()
        {
            m_AvailableProjects = null;
    
            try
            {
                var cancellationTokenSrc = new CancellationTokenSource();
                m_AvailableProjects = await PlatformServices.ProjectProvider.GetCurrentUserProjectList(m_CurrentOrganization, m_DefaultPagination, cancellationTokenSrc.Token);
            }
            catch (OperationCanceledException oe)
            {
                Debug.LogError(oe);
            }
            catch (AggregateException e)
            {
                Debug.LogError(e.InnerException);
            }
            catch (Exception e)
            {
                Debug.LogError(e);
            }
        }
    
        public void GetPreviousProjects()
        {
            m_AvailableProjects = m_AvailableProjects?.PreviousPage as IProjectPage;
        }
    
        public Task GetNextAvailableProjectsAsync()
        {
            return Task.CompletedTask;
        }
    
        public void GetPreviousAssets()
        {
            m_AvailableAssets = m_AvailableAssets?.PreviousPage as IAssetPage;
        }
    
        public Task GetNextAvailableAssetsAsync()
        {
            return Task.CompletedTask;
        }
    
        public async Task CreateAssetAsync()
        {
            var assetCreation = new AssetCreation
            {
                Organization = m_CurrentOrganization,
                Project = m_CurrentProject,
                Name = "GrayTexture_0",
                Description = $"Documentation example asset creation.",
                Type = nameof(Texture2D),
                Version = 1,
                VersionName = "1.0.0"
            };
    
            var cancellationTokenSrc = new CancellationTokenSource(k_DefaultCancellationTimeout);
    
            try
            {
                var asset = await PlatformServices.AssetManager.CreateAssetAsync(assetCreation, cancellationTokenSrc.Token);
                if (asset != null)
                {
                    // Refresh available assets
                    await GetAssetsAsync();
    
                    // Set created asset as current asset
                    CurrentAsset = asset;
                }
            }
            catch (Exception e)
            {
                Debug.LogError($"Failed to create asset. {e.Message}");
                throw;
            }
        }
    
        public async Task UpdateAssetAsync(IAsset asset)
        {
            try
            {
                var cancellationTokenSrc = new CancellationTokenSource(k_DefaultCancellationTimeout);
    
                await PlatformServices.AssetManager.UpdateAssetAsync(asset, cancellationTokenSrc.Token);
            }
            catch (OperationCanceledException oe)
            {
                Debug.LogError(oe);
            }
            catch (AggregateException e)
            {
                Debug.LogError(e.InnerException);
            }
            catch (Exception e)
            {
                Debug.LogError(e);
            }
        }
    
        public async Task DeleteAssetAsync(IAsset asset)
        {
            try
            {
                var cancellationTokenSrc = new CancellationTokenSource(k_DefaultCancellationTimeout);
                await PlatformServices.AssetManager.DeleteAssetAsync(asset, cancellationTokenSrc.Token);
    
                // Refresh available assets
                await GetAssetsAsync();
    
                // Reset current asset
                CurrentAsset = null;
            }
            catch (OperationCanceledException oe)
            {
                Debug.LogError(oe);
            }
            catch (AggregateException e)
            {
                Debug.LogError(e.InnerException);
            }
            catch (Exception e)
            {
                Debug.LogError(e);
            }
        }
    
        async Task GetAssetsAsync()
        {
            m_AvailableAssets = null;
            CurrentAsset = null;
    
            try
            {
                var cancellationTokenSrc = new CancellationTokenSource(k_DefaultCancellationTimeout);
                m_AvailableAssets = await PlatformServices.AssetManager.SearchAsync(new AssetSearchFilter(m_CurrentOrganization, m_CurrentProject), m_DefaultPagination, cancellationTokenSrc.Token);
            }
            catch (OperationCanceledException oe)
            {
                Debug.LogError(oe);
            }
            catch (AggregateException e)
            {
                Debug.LogError(e.InnerException);
            }
            catch (Exception e)
            {
                Debug.LogError(e);
            }
        }
    }
    
    

    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 assets of the selected project.
    • Provides the functions to create, read, update, delete assets.

    Create the UI for navigating assets

    To create a simple UI for navigating assets, do the following:

    Open the AssetManagementUI script you created earlier and replace the contents of the file with the following code sample:

    
    using System;
    using Unity.Cloud.Identity;
    using UnityEditor;
    using UnityEngine;
    
    public class AssetManagementUI : MonoBehaviour
    {
        protected readonly AssetManagementBehaviour m_Behaviour = new();
        IAuthenticationStateProvider m_AuthenticationStateProvider;
    
        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.GetProjectsAsync();
                    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);
    
                GUILayout.BeginVertical();
    
                GUILayout.Label($"{m_Behaviour.CurrentOrganization.Name} >> {m_Behaviour.CurrentProject.Name}");
                GUILayout.Space(10f);
    
                SelectAnAsset();
    
                GUILayout.Space(5f);
    
                ProjectActions();
    
                GUILayout.EndVertical();
    
                GUILayout.Space(50);
    
                AssetActions();
            }
    
            GUILayout.EndHorizontal();
        }
    
        protected virtual void ProjectActions()
        {
            // Add additional project related actions here.
        }
    
        protected virtual void AssetActions()
        {
            ManageAnAsset();
    
            // Add additional asset related 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 projectPage = m_Behaviour.AvailableProjects;
            if (projectPage != null)
            {
                var projects = projectPage.Elements;
    
                for (var i = 0; i < projects.Length; ++i)
                {
                    if (GUILayout.Button(projects[i].Name))
                    {
                        m_Behaviour.SetSelectedProject(projects[i]);
                    }
                }
    
                GUILayout.BeginHorizontal();
    
                EditorGUI.BeginDisabledGroup(projectPage.PreviousPage == null);
    
                // Go back to select a different scene.
                if (GUILayout.Button("Previous Page"))
                {
                    m_Behaviour.GetPreviousProjects();
                }
    
                EditorGUI.EndDisabledGroup();
    
                EditorGUI.BeginDisabledGroup(string.IsNullOrEmpty(projectPage.NextPageToken));
    
                // Go back to select a different scene.
                if (GUILayout.Button("Next Page"))
                {
                    _ = m_Behaviour.GetNextAvailableProjectsAsync();
                }
    
                EditorGUI.EndDisabledGroup();
    
                GUILayout.EndHorizontal();
            }
            else
            {
                GUILayout.Label("Loading...");
            }
    
            GUILayout.EndVertical();
        }
    
        void SelectAnAsset()
        {
            GUILayout.BeginVertical(EditorStyles.helpBox);
    
            GUILayout.Label("Available Assets:");
            GUILayout.Space(10);
    
            var assetPage = m_Behaviour.AvailableAssets;
            if (assetPage != null)
            {
                var assets = assetPage.Elements;
    
                for (var i = 0; i < assets.Length; ++i)
                {
                    if (GUILayout.Button(assets[i].Name))
                    {
                        m_Behaviour.CurrentAsset = assets[i];
                        Debug.Log($"Selected: {assets[i].Name}");
                    }
                }
    
                GUILayout.BeginHorizontal();
    
                EditorGUI.BeginDisabledGroup(assetPage.PreviousPage == null);
    
                // Go back to select a different scene.
                if (GUILayout.Button("Previous Page"))
                {
                    m_Behaviour.GetPreviousAssets();
                }
    
                EditorGUI.EndDisabledGroup();
    
                EditorGUI.BeginDisabledGroup(string.IsNullOrEmpty(assetPage.NextPageToken));
    
                // Go back to select a different scene.
                if (GUILayout.Button("Next Page"))
                {
                    _ = m_Behaviour.GetNextAvailableAssetsAsync();
                }
    
                EditorGUI.EndDisabledGroup();
    
                GUILayout.EndHorizontal();
            }
            else
            {
                GUILayout.Label("Loading...");
            }
    
            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();
            }
        }
    
        void ManageAnAsset()
        {
            GUILayout.BeginVertical();
    
            GUILayout.Label("Manage:");
            GUILayout.Space(10);
    
            if (GUILayout.Button("Create new asset", GUILayout.Width(150f)))
            {
                _ = m_Behaviour.CreateAssetAsync();
            }
            GUILayout.Space(5f);
    
            if (m_Behaviour.CurrentAsset == null)
            {
                GUILayout.Label(" ! No asset selected !");
            }
            else
            {
                GUILayout.Label("Asset selected:");
                GUILayout.Space(5f);
    
                DisplayAsset(m_Behaviour.CurrentAsset);
            }
    
            GUILayout.EndVertical();
        }
    
        protected virtual void DisplayAsset(IAsset asset)
        {
            GUILayout.BeginHorizontal();
    
            var nameValue = GUILayout.TextField(asset.Name, GUILayout.Width(100f));
            if(nameValue != asset.Name)
            {
                asset.Name = nameValue;
            }
            GUILayout.Space(5f);
    
            var versionNameValue = GUILayout.TextField(asset.VersionName, GUILayout.Width(50f));
            if(versionNameValue != asset.VersionName)
            {
                asset.VersionName = versionNameValue;
            }
            GUILayout.Space(5f);
    
            GUILayout.Label(asset.Status);
            GUILayout.Space(5f);
    
            if (GUILayout.Button("Update"))
            {
                _ = m_Behaviour.UpdateAssetAsync(asset);
            }
            GUILayout.Space(5f);
    
            if (GUILayout.Button("Delete"))
            {
                _ = m_Behaviour.DeleteAssetAsync(asset);
            }
            GUILayout.Space(5f);
    
            GUILayout.EndHorizontal();
        }
    }
    
    

    The script does the following:

    • Registers to the IAuthenticator to track login changes.
    • Creates an instance of an AssetManagementBehaviour.
    • Creates a simple UI flow for selecting organizations, projects and do CRUD operations on assets.
    Back to top
    Terms of use
    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