Skip to content

Commit

Permalink
added Asset Workflow demo with GUI, add RemoveLabel, a few minor addi…
Browse files Browse the repository at this point in the history
…tions
  • Loading branch information
CodeSmile-0000011110110111 committed Jan 29, 2024
1 parent 8d1a538 commit 495ac71
Show file tree
Hide file tree
Showing 17 changed files with 486 additions and 112 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Change Log

#### v1.8.5 - Jan 29, 2024

- added Asset.File.FindPaths overload accepting Path[]
- added Asset.Label.GetAll overload accepting Path
- added Asset.Label.Remove and Asset().RemoveLabel
- removed add sub-asset check for ".asset" extension. Turns out you can also add subassets to a .mesh extension asset and there may be others.

#### v1.8.4 - Jan 24, 2024

- added asset lifetime sample script
Expand Down
75 changes: 45 additions & 30 deletions Editor/Asset.File.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2021-2023 Steffen Itterheim
// Copyright (C) 2021-2024 Steffen Itterheim
// Refer to included LICENSE file for terms and conditions.

using System;
Expand Down Expand Up @@ -61,6 +61,8 @@ public static class File
/// <remarks>
/// CAUTION:
/// - Importing an asset and subsequently trying to load the asset within the callback will return null.
/// - For that reason you cannot create new Asset instances or call methods that create Asset instances, such as Copy,
/// during batch editing.
/// - When 'externally' modifying files and importing those, consider the above implication. You need to defer loading
/// and working with these objects. Calling BatchEditing twice is good practice (first modify & import, then load the
/// assets).
Expand Down Expand Up @@ -98,8 +100,7 @@ public static void BatchEditing([NotNull] Action massAssetFileEditAction)
/// - <see cref="CodeSmileEditor.Asset.File.Create(String,CodeSmileEditor.Asset.Path)" />
/// - <see cref="CodeSmileEditor.Asset.File.Create(Object,CodeSmileEditor.Asset.Path)" />
/// </seealso>
public static Object Create([NotNull] Byte[] contents, [NotNull] Path path) =>
CreateInternal(contents, path);
public static Object Create([NotNull] Byte[] contents, [NotNull] Path path) => CreateInternal(contents, path);

/// <summary>
/// Writes the byte array to disk, then imports and loads the asset. Generates a unique file name
Expand All @@ -114,8 +115,7 @@ public static Object Create([NotNull] Byte[] contents, [NotNull] Path path) =>
/// - <see cref="CodeSmileEditor.Asset.File.CreateAsNew(String,CodeSmileEditor.Asset.Path)" />
/// - <see cref="CodeSmileEditor.Asset.File.CreateAsNew(Object,CodeSmileEditor.Asset.Path)" />
/// </seealso>
public static Object CreateAsNew([NotNull] Byte[] contents, [NotNull] Path path) =>
CreateInternal(contents, path.UniqueFilePath);
public static Object CreateAsNew([NotNull] Byte[] contents, [NotNull] Path path) => CreateInternal(contents, path.UniqueFilePath);

/// <summary>
/// Writes the string to disk, then imports and loads the asset. Overwrites any existing file.
Expand All @@ -129,8 +129,7 @@ public static Object CreateAsNew([NotNull] Byte[] contents, [NotNull] Path path)
/// - <see cref="CodeSmileEditor.Asset.File.Create(Byte[],CodeSmileEditor.Asset.Path)" />
/// - <see cref="CodeSmileEditor.Asset.File.Create(Object,CodeSmileEditor.Asset.Path)" />
/// </seealso>
public static Object Create([NotNull] String contents, [NotNull] Path path) =>
CreateInternal(contents, path);
public static Object Create([NotNull] String contents, [NotNull] Path path) => CreateInternal(contents, path);

/// <summary>
/// Writes the string to disk, then imports and loads the asset. Generates a unique file name
Expand All @@ -145,8 +144,7 @@ public static Object Create([NotNull] String contents, [NotNull] Path path) =>
/// - <see cref="CodeSmileEditor.Asset.File.CreateAsNew(Byte[],CodeSmileEditor.Asset.Path)" />
/// - <see cref="CodeSmileEditor.Asset.File.CreateAsNew(Object,CodeSmileEditor.Asset.Path)" />
/// </seealso>
public static Object CreateAsNew([NotNull] String contents, [NotNull] Path path) =>
CreateInternal(contents, path.UniqueFilePath);
public static Object CreateAsNew([NotNull] String contents, [NotNull] Path path) => CreateInternal(contents, path.UniqueFilePath);

/// <summary>
/// Writes the object to disk. Overwrites any existing file.
Expand All @@ -162,8 +160,7 @@ public static Object CreateAsNew([NotNull] String contents, [NotNull] Path path)
/// - <see cref="CodeSmileEditor.Asset.File.CreateOrLoad{T}" />
/// - <a href="https://docs.unity3d.com/ScriptReference/AssetDatabase.CreateAsset.html">AssetDatabase.CreateAsset</a>
/// </seealso>
public static Object Create([NotNull] Object instance, [NotNull] Path path) =>
CreateInternal(instance, path);
public static Object Create([NotNull] Object instance, [NotNull] Path path) => CreateInternal(instance, path);

/// <summary>
/// Writes the object to disk. Generates a unique file name if an asset exists at the path.
Expand All @@ -179,8 +176,7 @@ public static Object Create([NotNull] Object instance, [NotNull] Path path) =>
/// - <see cref="CodeSmileEditor.Asset.File.CreateOrLoad{T}" />
/// - <a href="https://docs.unity3d.com/ScriptReference/AssetDatabase.CreateAsset.html">AssetDatabase.CreateAsset</a>
/// </seealso>
public static Object CreateAsNew([NotNull] Object instance, [NotNull] Path path) =>
CreateInternal(instance, path.UniqueFilePath);
public static Object CreateAsNew([NotNull] Object instance, [NotNull] Path path) => CreateInternal(instance, path.UniqueFilePath);

/// <summary>
/// Loads or creates an asset at path.
Expand Down Expand Up @@ -339,13 +335,12 @@ public static void
/// - <a href="https://docs.unity3d.com/ScriptReference/AssetDatabase.ImportAsset.html">AssetDatabase.ImportAsset</a>
/// </seealso>
public static void
Import([NotNull] String[] paths, ImportAssetOptions options = ImportAssetOptions.Default) =>
BatchEditing(
() =>
{
foreach (var path in paths)
AssetDatabase.ImportAsset(path, options);
});
Import([NotNull] String[] paths, ImportAssetOptions options = ImportAssetOptions.Default) => BatchEditing(
() =>
{
foreach (var path in paths)
AssetDatabase.ImportAsset(path, options);
});

/// <summary>
/// Loads an asset at path.
Expand Down Expand Up @@ -491,10 +486,9 @@ public static AssetDatabaseLoadOperation LoadAsync([NotNull] Path path, Int64 lo
/// </a>
/// </seealso>
[ExcludeFromCodeCoverage] // simple relay
public static String[] Find([NotNull] String filter, String[] searchInFolders = null) =>
searchInFolders == null
? AssetDatabase.FindAssets(filter)
: AssetDatabase.FindAssets(filter, searchInFolders);
public static String[] Find([NotNull] String filter, String[] searchInFolders = null) => searchInFolders == null
? AssetDatabase.FindAssets(filter)
: AssetDatabase.FindAssets(filter, searchInFolders);

/// <summary>
/// Finds asset GUIDs by the given filter criteria.
Expand Down Expand Up @@ -526,8 +520,7 @@ public static GUID[] FindGuids([NotNull] String filter, String[] searchInFolders
/// <remarks>Converts the list of string guids from CodeSmileEditor.Asset.File.Find to actual Paths.</remarks>
/// <param name="filter">A search filter string.</param>
/// <param name="searchInFolders">
/// A list of folders to recursively search for files. Limiting the searched folders speeds
/// up Find.
/// A list of folders to recursively search for files. Limiting the searched folders speeds up Find.
/// </param>
/// <returns>An Path array. Empty array if there were no search results.</returns>
/// <seealso cref="">
Expand All @@ -544,6 +537,29 @@ public static GUID[] FindGuids([NotNull] String filter, String[] searchInFolders
public static Path[] FindPaths([NotNull] String filter, String[] searchInFolders = null) =>
Find(filter, searchInFolders).Select(guid => Path.Get(new GUID(guid))).ToArray();

/// <summary>
/// Finds asset paths by the given filter criteria.
/// </summary>
/// <remarks>Converts the list of string guids from CodeSmileEditor.Asset.File.Find to actual Paths.</remarks>
/// <param name="filter">A search filter string.</param>
/// <param name="searchInFolders">
/// A list of folder paths to recursively search for files. Limiting the searched folders speeds up Find.
/// </param>
/// <returns>An Path array. Empty array if there were no search results.</returns>
/// <seealso cref="">
/// - <see cref="CodeSmileEditor.Asset.File.Find" />
/// - <see cref="CodeSmileEditor.Asset.File.FindGuids" />
/// - <a href="https://docs.unity3d.com/ScriptReference/AssetDatabase.FindAssets.html">AssetDatabase.FindAssets</a>
/// -
/// <a href="https://forum.unity.com/threads/please-document-assetdatabase-findassets-filters.964907/">
/// Search Filter
/// String Examples
/// </a>
/// </seealso>
[ExcludeFromCodeCoverage] // simple relay
public static Path[] FindPaths([NotNull] String filter, Path[] searchInFolders = null) =>
FindPaths(filter, Path.ToStrings(searchInFolders));

/// <summary>
/// Copies an asset from source to destination path. Overwrites any existing assets.
/// </summary>
Expand Down Expand Up @@ -656,8 +672,8 @@ public static Boolean Move([NotNull] Path sourcePath, [NotNull] Path destination
/// - <see cref="CodeSmileEditor.Asset.GetLastErrorMessage" />
/// - <a href="https://docs.unity3d.com/ScriptReference/AssetDatabase.RenameAsset.html">AssetDatabase.RenameAsset</a>
/// </seealso>
public static Boolean Rename([NotNull] Path path, String newFileName) =>
String.IsNullOrEmpty(newFileName) == false && Succeeded(AssetDatabase.RenameAsset(path, newFileName));
public static Boolean Rename([NotNull] Path path, String newFileName) => String.IsNullOrEmpty(newFileName) == false &&
Succeeded(AssetDatabase.RenameAsset(path, newFileName));

/// <summary>
/// Returns true if the given object can be opened (edited) by the Unity editor.
Expand All @@ -671,8 +687,7 @@ public static Boolean Rename([NotNull] Path path, String newFileName) =>
/// <a href="https://docs.unity3d.com/ScriptReference/AssetDatabase.CanOpenAssetInEditor.html">AssetDatabase.CanOpenAssetInEditor</a>
/// </seealso>
[ExcludeFromCodeCoverage] // simple relay
public static Boolean CanOpenInEditor([NotNull] Object instance) =>
CanOpenInEditor(instance.GetInstanceID());
public static Boolean CanOpenInEditor([NotNull] Object instance) => CanOpenInEditor(instance.GetInstanceID());

/// <summary>
/// Returns true if the given object can be opened (edited) by the Unity editor.
Expand Down
31 changes: 30 additions & 1 deletion Editor/Asset.Label.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// Copyright (C) 2021-2023 Steffen Itterheim
// Copyright (C) 2021-2024 Steffen Itterheim
// Refer to included LICENSE file for terms and conditions.

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using UnityEditor;
using Object = UnityEngine.Object;

Expand All @@ -28,6 +29,18 @@ public static class Label
/// </seealso>
public static String[] GetAll([NotNull] Object asset) => AssetDatabase.GetLabels(asset);

/// <summary>
/// Returns an asset's labels.
/// </summary>
/// <param name="path">Path to an asset.</param>
/// <returns>The labels of the asset or an empty array.</returns>
/// <seealso cref="">
/// - <see cref="CodeSmileEditor.Asset.Label.Add" />
/// - <see cref="CodeSmileEditor.Asset.Label.SetAll" />
/// - <a href="https://docs.unity3d.com/ScriptReference/AssetDatabase.GetLabels.html">AssetDatabase.GetLabels</a>
/// </seealso>
public static String[] GetAll([NotNull] Path path) => AssetDatabase.GetLabels(path.Guid);

/// <summary>
/// Returns an asset's labels.
/// </summary>
Expand Down Expand Up @@ -97,11 +110,27 @@ public static void Add([NotNull] Object asset, [NotNull] String[] labels)
/// </summary>
/// <param name="asset">Instance of an asset.</param>
/// <seealso cref="">
/// - <see cref="CodeSmileEditor.Asset.Label.Remove" />
/// - <see cref="CodeSmileEditor.Asset.Label.GetAll" />
/// - <see cref="CodeSmileEditor.Asset.Label.SetAll" />
/// - <a href="https://docs.unity3d.com/ScriptReference/AssetDatabase.ClearLabels.html">AssetDatabase.ClearLabels</a>
/// </seealso>
public static void ClearAll([NotNull] Object asset) => AssetDatabase.ClearLabels(asset);

/// <summary>
/// Removes a label from an asset. Does nothing if the label doesn't exist.
/// </summary>
/// <param name="asset">Instance of an asset.</param>
/// <param name="label">Label to remove.</param>
/// <seealso cref="">
/// - <see cref="CodeSmileEditor.Asset.Label.ClearAll" />
/// </seealso>
public static void Remove(Object asset, String label)
{
var labels = GetAll(asset).ToList();
labels.Remove(label);
SetAll(asset, labels.ToArray());
}
}
}
}
4 changes: 2 additions & 2 deletions Editor/Asset.Path.Static.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) 2021-2023 Steffen Itterheim
// Copyright (C) 2021-2024 Steffen Itterheim
// Refer to included LICENSE file for terms and conditions.

using System;
Expand Down Expand Up @@ -322,7 +322,7 @@ public static Path UniquifyFileName([NotNull] Path path)
/// </summary>
/// <param name="paths">Input paths.</param>
/// <returns>Relative paths as strings.</returns>
public static String[] ToStrings([NotNull] IEnumerable<Path> paths) => paths.Cast<String>().ToArray();
public static String[] ToStrings([NotNull] IEnumerable<Path> paths) => paths.Select(path => (String)path).ToArray();

internal static Path UniquifyAsNeeded([NotNull] Path path, Boolean overwriteExisting) =>
overwriteExisting ? path : path.UniqueFilePath;
Expand Down
1 change: 0 additions & 1 deletion Editor/Asset.SubAsset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ public static void Add([NotNull] Object subAssetInstance, [NotNull] Object asset
ThrowIf.SubObjectIsGameObject(subAssetInstance);
ThrowIf.AlreadyAnAsset(subAssetInstance);
ThrowIf.ArgumentIsNull(asset, nameof(asset));
ThrowIf.NotAnAssetWithAssetExtension(asset);

AssetDatabase.AddObjectToAsset(subAssetInstance, asset);
}
Expand Down
7 changes: 0 additions & 7 deletions Editor/Asset.ThrowIf.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,6 @@ public static void SubObjectIsGameObject(UnityEngine.Object subObject)
throw new ArgumentException($"sub assets must not be of type GameObject: {subObject}");
}

public static void NotAnAssetWithAssetExtension(UnityEngine.Object assetObject)
{
var path = Path.Get(assetObject);
if (path.Extension.Equals(".asset") == false)
throw new ArgumentException("sub assets only supported with '.asset' extension: {path}");
}

public static void ExtensionIsNotUnityPackage(Path path)
{
if (path.Extension.ToLower().Equals(".unitypackage") == false)
Expand Down
Loading

0 comments on commit 495ac71

Please sign in to comment.