docs.unity3d.com
Search Results for

    Show / Hide Table of Contents

    Use case: Create and upload files to a dataset

    You can use the Unity Cloud Assets package to:

    • view the files of an asset.
    • upload files to an asset's dataset.
    • reference files between datasets.

    The SDK supports several workflows for users with different roles.

    Organization or Asset Manager Project role View files Upload new file Add/remove file references
    Asset Management Viewer yes no no
    Asset Management Consumer yes no no
    Asset Management Contributor yes yes yes
    Organization Owner yes yes yes

    Before you start

    Before you start, you must:

    1. Set up a Unity scene in the Unity Editor with an Organization and Project browser. See Get started with Assets for more information.

    2. Have some assets in the cloud. There are several ways to do so:

      • You can create assets through the Get started with Assets.
      • You can create assets through the dashboard; see the Managing assets on the dashboard documentation.

    How do I...?

    List an asset's datasets and files

    To list datasets, open the AssetManagementBehaviour script you created and add the following code to the end of the class:

    
    public List<IDataset> Datasets { get; private set; }
    
    public async Task GetDatasets()
    {
        Datasets = null;
    
        if (CurrentAsset == null) return;
    
        var datasets = new List<IDataset>();
        var asyncList = CurrentAsset.ListDatasetsAsync(Range.All, CancellationToken.None);
        await foreach (var dataset in asyncList)
        {
            datasets.Add(dataset);
        }
    
        Datasets = datasets;
    }
    
    

    To list files, open the AssetManagementBehaviour script you created and add the following code to the end of the class:

    
    public Dictionary<DatasetId, IEnumerable<IFile>> DatasetFiles { get; } = new();
    
    public async Task GetFilesAsync(DatasetId datasetId)
    {
        DatasetFiles.Remove(datasetId);
    
        var dataset = Datasets?.FirstOrDefault(d => d.Descriptor.DatasetId == datasetId);
        if (dataset == null) return;
    
        DatasetFiles[datasetId] = null;
    
        var files = new List<IFile>();
        var fileList = dataset.ListFilesAsync(Range.All, CancellationToken.None);
        await foreach (var file in fileList)
        {
            files.Add(file);
        }
    
        DatasetFiles[datasetId] = files;
    }
    
    

    Upload a file

    To upload a file to an asset's dataset, follow these steps:

    1. Open the AssetManagementBehaviour script you created.
    2. Add the following code to the end of the class:
    
    class LogProgress : IProgress<HttpProgress>
    {
        public void Report(HttpProgress value)
        {
            if (!value.UploadProgress.HasValue) return;
    
            Debug.Log($"Upload progress: {value.UploadProgress * 100} %");
        }
    }
    
    public async Task UploadFile(IDataset dataset, string filePath)
    {
        var fileCreation = new FileCreation(Path.GetFileName(filePath))
        {
            Description = "Documentation example asset file creation.",
            Tags = new List<string> {"Texture", "Gray"}
        };
    
        try
        {
            var progress = new LogProgress();
    
            var fileStream = File.OpenRead(filePath);
            var file = await dataset.UploadFileAsync(fileCreation, fileStream, progress, default);
    
            _ = GetFilesAsync(dataset.Descriptor.DatasetId);
    
            Debug.Log($"Asset file upload: {file.Descriptor.Path} added and uploaded.");
        }
        catch (Exception e)
        {
            Debug.LogError($"Failed to upload file: {fileCreation.Path}. {e}");
        }
    }
    
    

    The code snippet does the following:

    • Displays a UI button for creating a new file.
    • When the button is clicked, a file dialog opens to select a file.
    • When a file is selected, a new file definition is created and the file content is uploaded.
    • Prints a progress log for the upload to the console.
    • Prints a message to the console when the upload is complete OR an error message if the upload fails.

    Reference a file in a different dataset

    To reference a file in a different dataset, follow these steps:

    1. Open the AssetManagementBehaviour script you created.
    2. Add the following code to the end of the class:
    
    public async Task LinkFile(IDataset dataset, IFile file)
    {
        try
        {
            await dataset.AddExistingFileAsync(file.Descriptor.Path, file.Descriptor.DatasetId, CancellationToken.None);
            Debug.Log($"File: {file.Descriptor.Path} linked to dataset {dataset.Descriptor.DatasetId}.");
        }
        catch (Exception e)
        {
            Debug.LogError($"Failed to link asset file: {file.Descriptor.Path}. {e}");
        }
    }
    
    

    The code snippet does the following:

    • Links a file to a dataset.
    • Prints a message to the console on success OR an error message if the linking fails.

    Remove a file reference from a dataset

    To remove a file reference from a dataset, follow these steps:

    1. Open the AssetManagementBehaviour script you created.
    2. Add the following code to the end of the class:
    
    public async Task UnlinkFile(IDataset dataset, IFile file)
    {
        try
        {
            await dataset.RemoveFileAsync(file.Descriptor.Path, CancellationToken.None);
            Debug.Log($"File: {file.Descriptor.Path} unlinked from dataset {dataset.Descriptor.DatasetId}.");
    
            _ = GetFilesAsync(dataset.Descriptor.DatasetId);
        }
        catch (Exception e)
        {
            Debug.LogError($"Failed to unlink asset file: {file.Descriptor.Path}. {e}");
        }
    }
    
    

    The code snippet does the following:

    • Unlinks a file from a dataset.
    • Prints a message to the console on success OR an error message if the unlinking fails.

    Add the UI for creating files

    To create UI for creating files, follow these steps:

    1. In your Unity Project window, go to Assets > Scripts.
    2. Select and hold the Assets/Scripts folder.
    3. Go to Create > C# Script. Name your script UseCaseFileCreationExampleUI.
    4. Open the UseCaseFileCreationExampleUI script you created and replace the contents of the file with the following code sample:
    
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Threading;
    using System.Threading.Tasks;
    using Unity.Cloud.Assets;
    using Unity.Cloud.Common;
    using UnityEngine;
    
    public class UseCaseFileCreationExampleUI : IAssetManagementUI
    {
        readonly AssetManagementBehaviour m_Behaviour;
    
        public UseCaseFileCreationExampleUI(AssetManagementBehaviour behaviour)
        {
            m_Behaviour = behaviour;
        }
    
        public void OnGUI() { }
    }
    
    
    1. In the same script, replace the OnGUI function with the following code:
    
            IAsset m_CurrentAsset;
            Vector2 m_DatasetsScrollPosition;
            Dictionary<DatasetId, bool> m_Expanded = new();
    
            public void OnGUI()
            {
                if (!m_Behaviour.IsProjectSelected) return;
    
                if (m_CurrentAsset != m_Behaviour.CurrentAsset)
                {
                    m_CurrentAsset = m_Behaviour.CurrentAsset;
                    _ = m_Behaviour.GetDatasets();
                }
    
                if (m_CurrentAsset == null)
                {
                    GUILayout.Label(" ! No asset selected !");
                    return;
                }
    
                if (m_Behaviour.Datasets == null)
                {
                    GUILayout.Label("Loading datasets...");
                    return;
                }
    
                GUILayout.BeginVertical();
    
                if (GUILayout.Button("Refresh Datasets", GUILayout.Width(120)))
                {
                    _ = m_Behaviour.GetDatasets();
                }
    
                GUILayout.Space(5f);
    
                DisplayDatasets(m_Behaviour.Datasets.ToArray());
    
                GUILayout.EndVertical();
            }
    
            void DisplayDatasets(IReadOnlyCollection<IDataset> datasets)
            {
                if (datasets.Count == 0)
                {
                    GUILayout.Label("No datasets.");
                    return;
                }
    
                m_DatasetsScrollPosition = GUILayout.BeginScrollView(m_DatasetsScrollPosition, GUILayout.Height(Screen.height * 0.8f));
    
                foreach (var dataset in datasets)
                {
                    DisplayDataset(dataset);
    
                    GUILayout.Space(10f);
                }
    
                GUILayout.EndScrollView();
            }
    
            void DisplayDataset(IDataset dataset)
            {
                GUILayout.BeginHorizontal();
    
                GUILayout.Label(dataset.Name);
    
                GUILayout.Space(5f);
    
    #if UNITY_EDITOR
                if (GUILayout.Button("Upload new file", GUILayout.Width(100)))
                {
                    var filePath = UnityEditor.EditorUtility.OpenFilePanel("File to upload", "Assets", string.Empty);
                    if (!string.IsNullOrEmpty(filePath))
                        _ = m_Behaviour.UploadFile(dataset, filePath);
                }
    #endif
    
                var expanded = m_Expanded.GetValueOrDefault(dataset.Descriptor.DatasetId);
                if (GUILayout.Button(expanded ? "-" : "+", GUILayout.Width(20f)))
                {
                    expanded = !expanded;
                    m_Expanded[dataset.Descriptor.DatasetId] = expanded;
    
                    if (!expanded)
                    {
                        m_Behaviour.DatasetFiles.Remove(dataset.Descriptor.DatasetId);
                    }
                }
    
                GUILayout.EndHorizontal();
    
                if (expanded)
                {
                    GUILayout.BeginHorizontal();
    
                    GUILayout.Space(25);
    
                    DisplayFiles(dataset);
    
                    GUILayout.EndHorizontal();
                }
    
                if (m_SelectedFile != null)
                {
                    m_WindowRect = GUILayout.Window(0, m_WindowRect, DisplayWindow, "Select files to link");
                }
            }
    
            void DisplayFiles(IDataset dataset)
            {
                if (!m_Behaviour.DatasetFiles.ContainsKey(dataset.Descriptor.DatasetId))
                {
                    _ = m_Behaviour.GetFilesAsync(dataset.Descriptor.DatasetId);
                }
    
                var files = m_Behaviour.DatasetFiles.GetValueOrDefault(dataset.Descriptor.DatasetId);
    
                if (files == null)
                {
                    GUILayout.Label("Loading files...");
                    return;
                }
    
                var enumerable = files.ToArray();
                if (!enumerable.Any())
                {
                    GUILayout.Label("No files.");
                    return;
                }
    
                GUILayout.BeginVertical();
    
                foreach (var file in enumerable)
                {
                    DisplayFile(dataset, file);
                }
    
                GUILayout.EndVertical();
            }
    
            void DisplayFile(IDataset dataset, IFile file)
            {
                GUILayout.BeginHorizontal();
    
                GUILayout.Label($"{file.Descriptor.Path} ({file.SizeBytes} kb)");
    
                if (GUILayout.Button("Link to", GUILayout.Width(60)))
                {
                    m_WindowRect = new Rect(Screen.width * 0.4f, Screen.height * 0.4f, Screen.width * 0.2f, Screen.height * 0.2f);
                    m_SelectedFile = file;
                    m_AvailableDatasets = m_Behaviour.Datasets?.Where(f => !m_SelectedFile.LinkedDatasets.Contains(dataset.Descriptor)).ToList();
                }
    
                if (GUILayout.Button("Unlink", GUILayout.Width(60)))
                {
                    _ = m_Behaviour.UnlinkFile(dataset, file);
                }
    
                GUILayout.EndHorizontal();
            }
    
            Rect m_WindowRect;
            IFile m_SelectedFile;
            List<IDataset> m_AvailableDatasets;
    
            void DisplayWindow(int windowId)
            {
                GUILayout.BeginVertical();
    
                GUILayout.Label($"Link {m_SelectedFile.Descriptor.Path} to:");
    
                if (m_AvailableDatasets.Count == 0)
                {
                    GUILayout.Label(" ! No datasets to link to !");
                }
                else
                {
                    for (var i = 0; i < m_AvailableDatasets.Count; ++i)
                    {
                        GUILayout.BeginHorizontal();
    
                        GUILayout.Label(m_AvailableDatasets[i].Name);
    
                        if (GUILayout.Button("Link", GUILayout.Width(60)))
                        {
                            _ = m_Behaviour.LinkFile(m_AvailableDatasets[i], m_SelectedFile);
                            m_AvailableDatasets.RemoveAt(i);
    
                            // Force a refresh of the dataset files, including the already linked ones of the selected one
                            foreach (var linkedDatasetId in m_SelectedFile.LinkedDatasets.Select(d => d.DatasetId))
                            {
                                m_Behaviour.DatasetFiles.Remove(linkedDatasetId);
                                m_Expanded.Remove(linkedDatasetId);
                            }
                            m_Behaviour.DatasetFiles.Remove(m_AvailableDatasets[i].Descriptor.DatasetId);
                            m_Expanded.Remove(m_AvailableDatasets[i].Descriptor.DatasetId);
    
                            GUILayout.EndHorizontal();
                            break;
                        }
    
                        GUILayout.EndHorizontal();
                    }
                }
    
                GUILayout.Space(10f);
    
                if (GUILayout.Button("Close", GUILayout.Width(60)))
                {
                    m_SelectedFile = null;
                    m_AvailableDatasets = null;
                }
    
                GUILayout.EndVertical();
            }
    
    
    1. Open the AssetManagementUI script you created and replace the contents of the Awake function with the following code:
    
    m_UI.Add(new OrganizationSelectionExampleUI(m_Behaviour));
    m_UI.Add(new ProjectSelectionExampleUI(m_Behaviour));
    m_UI.Add(new AssetSelectionExampleUI(m_Behaviour));
    m_UI.Add(new UseCaseFileCreationExampleUI(m_Behaviour));
    
    

    The code snippet does the following:

    • Provides a UI button to refresh the list of files within each dataset.
    • Provides UI buttons to trigger the creation of a new file within a dataset.
    • Provides a UI button to link an existing file to a dataset.
    • Provides a UI button for each existing file to unlink it from its dataset.
    In This Article
    Back to top
    Copyright © 2024 Unity Technologies — Trademarks and terms of use
    • Legal
    • Privacy Policy
    • Cookie Policy
    • Do Not Sell or Share My Personal Information
    • Your Privacy Choices (Cookie Settings)