【Unity】Addressable で指定ディレクトリ以下にあるアセットに自動でAddressを設定する

Addressable Asset Sysytem では Addressable Group の EditorWidow からアドレスを設定する作りとなっており、自動化したい場合は自前でなにかしらの処理を書く必要がある

大体同じ処理を書くと思うので自動的にアドレスを設定する PostProcessor を作成した

```csharp
using System;
using UnityEditor;
using UnityEditor.AddressableAssets;
using UnityEditor.AddressableAssets.Settings;

public class AddressablePostProcessor : AssetPostprocessor
{
    private static readonly string targetPath = "Assets/AddressableAsset/";
    
    private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
    {
        var dirty = false;
        dirty |= ChangeEntry(importedAssets, false);
        dirty |= ChangeEntry(deletedAssets, true);
        dirty |= ChangeEntry(movedAssets, false);
        
        if (dirty)
        {
            AssetDatabase.SaveAssets();
        }
    }

    private static bool ChangeEntry(string[] paths, bool delete)
    {
        var settings = AddressableAssetSettingsDefaultObject.Settings;
        var groups = settings.groups;
        var dirty = false;
       
        foreach (var path in paths)
        {
            if (!path.StartsWith(targetPath))
                continue;
            
            if (AssetDatabase.IsValidFolder(path))
                continue;

            var assetPath = path.Replace(targetPath, "");

            var targetGroup = settings.DefaultGroup;
            var rootIndex = assetPath.IndexOf(System.IO.Path.DirectorySeparatorChar, StringComparison.Ordinal);
            if (rootIndex >= 0)
            { 
                var rootPath = assetPath.Substring(0, rootIndex);
                var groupIndex = groups.FindIndex(g => g.Name == rootPath);
                if (groupIndex >= 0)
                {
                    targetGroup = groups[groupIndex];
                }
                else
                {
                    var groupTemplate = settings.GetGroupTemplateObject(0) as AddressableAssetGroupTemplate;
                    targetGroup = settings.CreateGroup(rootPath, false, false, false, null, groupTemplate.GetTypes());
                }
                
                assetPath = assetPath.Substring(rootIndex + 1);
            }

            var guid = AssetDatabase.AssetPathToGUID(path);
            if (delete)
            {
                settings.RemoveAssetEntry(guid);
            }
            else
            {
                var lastIndex = assetPath.LastIndexOf(".", StringComparison.Ordinal);
                var address = assetPath.Substring(0, lastIndex);
                
                var entry = settings.CreateOrMoveEntry(guid, targetGroup);
                if (entry.address == address)
                    continue;
                
                entry.address = address;
            }

            dirty = true;
        }

        return dirty;
    }
}
```

これを利用すると以下の様な構成の際に

![スクリーンショット 2023-08-06 21.05.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46655/4fff3303-0fb6-bcab-c52c-fd4271d69021.png)

このようなアドレスが自動的に設定される

![スクリーンショット 2023-08-06 21.06.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46655/991b2fb0-30b3-0208-f044-459beb19d0c2.png)