0
\$\begingroup\$

I have a ScriptedImporter that generates other assets in the same directory.

Whenever it happens, import progress bar pops in again, this time like Importing (iteration N).

I've tried to use AssetDatabase.DisallowAutoRefresh to circumvent this behavior but that failed.

Question:

How to prevent subsequent import iterations and rather group them to happen all at once ?

\$\endgroup\$
0
1
\$\begingroup\$

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 ScriptableObjects 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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.