Use case: Create and upload files
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:
Set up a Unity scene in the Unity Editor with an Organization and Project browser. See Get started with Assets for more information.
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 upload assets from existing Unity assets; see the Asset Database Uploader sample.
- 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; set; }
public async Task GetDatasets()
{
Datasets = new List<IDataset>();
await CurrentAsset.RefreshAsync(CancellationToken.None);
var asyncList = CurrentAsset.ListDatasetsAsync(Range.All, CancellationToken.None);
await foreach (var dataset in asyncList)
{
Datasets.Add(dataset);
}
}
To list files, open the AssetManagementBehaviour
script you created and add the following code to the end of the class:
public List<IFile> Files { get; set; }
public async Task GetFiles()
{
Files = new List<IFile>();
await CurrentAsset.RefreshAsync(CancellationToken.None);
var asyncList = CurrentAsset.ListFilesAsync(Range.All, CancellationToken.None);
await foreach (var file in asyncList)
{
Files.Add(file);
}
}
Upload a file
To upload a file to an asset's dataset, follow these steps:
- Open the
AssetManagementBehaviour
script you created. - Add the following code to the end of the class:
static readonly byte[] s_Bytes = new byte[]
{
100, 100, 100, 100, 100, 100, 100, 100, 100, 100
};
class LogProgress : IProgress<HttpProgress>
{
public void Report(HttpProgress value)
{
if (!value.UploadProgress.HasValue) return;
Debug.Log($"Upload progress: {value.UploadProgress * 100} %");
}
}
public async Task UploadAssetFile(IDataset dataset)
{
var fileCreation = new FileCreation
{
Path = $@"files/file_{DateTime.Now:MM-dd_HH-mm-ss}",
Description = "Documentation example asset file creation.",
Tags = new List<string> {"Texture", "Gray"}
};
var contentStream = new MemoryStream(s_Bytes);
var cancellationTokenSrc = new CancellationTokenSource();
try
{
var progress = new LogProgress();
var file = await dataset.UploadFileAsync(fileCreation, contentStream, progress, cancellationTokenSrc.Token);
Files.Add(file);
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:
- Creates a new definition for a file.
- Uploads the file content to the cloud.
- 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:
- Open the
AssetManagementBehaviour
script you created. - 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:
- Open the
AssetManagementBehaviour
script you created. - 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}.");
Files = null;
}
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:
- In your Unity Project window, go to Assets > Scripts.
- Select and hold the
Assets/Scripts
folder. - Go to Create > C# Script. Name your script
UseCaseFileCreationExampleUI
. - 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() { }
}
- In the same script, replace the
OnGUI
function with the following code:
IAsset m_CurrentAsset;
Vector2 m_DatasetsScrollPosition;
public void OnGUI()
{
if (!m_Behaviour.IsProjectSelected) return;
if (m_CurrentAsset != m_Behaviour.CurrentAsset)
{
m_CurrentAsset = m_Behaviour.CurrentAsset;
m_Behaviour.Datasets = null;
m_Behaviour.Files = null;
}
if (m_CurrentAsset == null)
{
GUILayout.Label(" ! No asset selected !");
return;
}
GUILayout.BeginVertical();
if (GUILayout.Button("Refresh All") || m_Behaviour.Datasets == null || m_Behaviour.Files == null)
{
_ = m_Behaviour.GetDatasets();
_ = m_Behaviour.GetFiles();
}
GUILayout.Label("Asset datasets:");
DisplayDatasets(m_Behaviour.Datasets?.ToArray() ?? Array.Empty<IDataset>());
GUILayout.EndVertical();
}
void DisplayDatasets(IReadOnlyList<IDataset> datasets)
{
if (datasets.Count == 0)
{
GUILayout.Label(" ! No datasets !");
}
else
{
var files = m_Behaviour.Files?.ToArray() ?? Array.Empty<IFile>();
m_DatasetsScrollPosition = GUILayout.BeginScrollView(m_DatasetsScrollPosition, GUILayout.Height(Screen.height * 0.8f));
for (var i = 0; i < datasets.Count; ++i)
{
var dataset = datasets[i];
DisplayDataset(dataset, files.Where(file => file.LinkedDatasets.Contains(dataset.Descriptor)).ToArray());
GUILayout.Space(10f);
}
GUILayout.EndScrollView();
}
}
void DisplayDataset(IDataset dataset, IReadOnlyCollection<IFile> files)
{
GUILayout.BeginHorizontal();
GUILayout.Label(dataset.Name);
GUILayout.Space(5f);
if (GUILayout.Button("Create new asset file"))
{
_ = m_Behaviour.UploadAssetFile(dataset);
}
GUI.enabled = m_SelectedDataset == null;
if (GUILayout.Button("Link asset file"))
{
m_WindowRect = new Rect(Screen.width * 0.4f, Screen.height * 0.4f, Screen.width * 0.2f, Screen.height * 0.2f);
m_SelectedDataset = dataset;
m_AvailableFiles = m_Behaviour.Files?.Where(f => !f.LinkedDatasets.Contains(dataset.Descriptor)).ToList();
}
GUI.enabled = true;
GUILayout.EndHorizontal();
if (m_SelectedDataset != null)
{
m_WindowRect = GUILayout.Window(0, m_WindowRect, DisplayWindow, "Select files to link");
}
if (files.Count == 0)
{
GUILayout.Label(" ! No files !");
}
else
{
foreach (var file in files)
{
DisplayAssetFile(dataset, file);
}
}
}
void DisplayAssetFile(IDataset dataset, IFile file)
{
GUILayout.BeginHorizontal();
GUILayout.Label($" > {file.Descriptor.Path} ({file.SizeBytes} kb)");
if (GUILayout.Button("Unlink"))
{
_ = m_Behaviour.UnlinkFile(dataset, file);
}
GUILayout.EndHorizontal();
}
Rect m_WindowRect;
IDataset m_SelectedDataset;
List<IFile> m_AvailableFiles;
void DisplayWindow(int windowId)
{
GUILayout.BeginVertical();
GUILayout.Label($"Link files to {m_SelectedDataset.Name}:");
if (m_AvailableFiles.Count == 0)
{
GUILayout.Label(" ! No files !");
}
else
{
for (var i = 0; i < m_AvailableFiles.Count; ++i)
{
GUILayout.BeginHorizontal();
GUILayout.Label(m_AvailableFiles[i].Descriptor.Path);
if (GUILayout.Button("Link"))
{
_ = m_Behaviour.LinkFile(m_SelectedDataset, m_AvailableFiles[i]);
m_AvailableFiles.RemoveAt(i);
GUILayout.EndHorizontal();
break;
}
GUILayout.EndHorizontal();
}
}
GUILayout.Space(10f);
if (GUILayout.Button("Close"))
{
m_SelectedDataset = null;
m_AvailableFiles = null;
_ = m_Behaviour.GetFiles();
}
GUILayout.EndVertical();
}
- Open the
AssetManagementUI
script you created and replace the contents of theAwake
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 UI buttons to trigger the creation of a new file on the asset.
- Displays a list of created files and provides a UI button to upload the file content.
Going further
For more a more in-depth look at file management, see the Asset Database Uploader sample.