By directly putting things in AssetImportContext
this problem will go.
Advantages:
- asset is a script and not a blank icon anymore
- it's importing faster
- assets are read-only, very interesting :D
- everything is in one place
- less assets to deal with
Disadvantages:
- all sub assets are in asset, pretty hard to navigate in project browser
- assets needs unique names, quite easy actually
- things like textures lose fully featured importer
A cool trick is to make a ZIP file in which you put whatever you want but then give it another extension so you can differentiate file formats.
I came up with this to decorate ScriptableObject
s trees:
[PublicAPI]
public interface IAsset
{
[NotNull]
string Name { get; set; } // this can be customized but should be unique then
[NotNull]
[ItemNotNull]
IEnumerable<IAsset> GetDescendants(); // to traverse tree
[NotNull]
string GetPrefix(); // for generating name automatically
}
public static class IAssetExtensions
{
public static void AddSelfAndDescendants(
[NotNull] this AssetImportContext context, [NotNull] IAsset asset, IAssetFlags flags = IAssetFlags.Default)
{
if (context is null)
throw new ArgumentNullException(nameof(context));
if (asset is null)
throw new ArgumentNullException(nameof(asset));
var generator = new UniqueNameGenerator();
var queue = new Queue<IAsset>(new[] {asset});
while (queue.Any())
{
var dequeue = queue.Dequeue();
if (dequeue is IAsset iAsset)
{
var descendants = iAsset.GetDescendants();
foreach (var descendant in descendants)
{
queue.Enqueue(descendant);
}
}
if (flags.HasFlagFast(IAssetFlags.Rename) && string.IsNullOrWhiteSpace(dequeue.Name))
dequeue.Name = generator.GetName(dequeue.GetPrefix());
context.AddObjectToAsset(dequeue.Name, dequeue as Object);
}
context.SetMainObject(asset as Object);
}
}
public sealed class UniqueNameGenerator
{
public UniqueNameGenerator([CanBeNull] IDictionary<string, int> dictionary = null)
{
Dictionary = dictionary ?? new Dictionary<string, int>();
}
[NotNull]
private IDictionary<string, int> Dictionary { get; }
[NotNull]
public string GetName([NotNull] string prefix)
{
if (string.IsNullOrWhiteSpace(prefix))
throw new ArgumentException("Value cannot be null or whitespace.", nameof(prefix));
if (!Dictionary.ContainsKey(prefix))
Dictionary.Add(prefix, default);
var suffix = Dictionary[prefix];
var unique = $"{prefix} {suffix}";
Dictionary[prefix]++;
return unique;
}
}
Summarized but you get the general idea.