📗

【Unity】Addressablesの登録を楽にする拡張機能

2024/11/28に公開

はじめに

初めての方も、そうでない方もこんにちは!
現役ゲームプログラマーのたむぼーです。
自己紹介を載せているので、気になる方は見ていただければ嬉しいです!

今回は
 Addressablesの登録を楽にする拡張機能
について紹介します

https://zenn.dev/tmb/articles/1072f8ea010299

準備

・Addressables

https://zenn.dev/tmb/articles/3ccdfb9eeef755

拡張コード

Addressablesの登録を楽にする拡張機能
AddressableSetter.cs
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEditor.AddressableAssets;
using UnityEditor.AddressableAssets.Settings;

namespace Editor
{
    public class AddressableSetter
    {
        private enum AddressableNameMode
        {
            /// <summary> フルパス</summary>
            FullPath,

            /// <summary> 拡張子を除いたフルパス</summary>
            FullPathWithoutExtension,

            /// <summary> 拡張子を除いたファイル名 </summary>
            FileNameWithoutExtension,

            /// <summary> 拡張子を除いた親フォルダ名とファイル名</summary>
            ParentAndFileNameWithoutExtension,
        }

        private const string MENU_ITEM_ROOT = "Assets/Tools/Addressable Setter/";

        /// <summary>
        /// フルパスで登録
        /// </summary>
        [MenuItem(MENU_ITEM_ROOT + "FullPath")]
        private static void SetterFullPath()
        {
            Setter(AddressableNameMode.FullPath);
        }

        /// <summary>
        /// 拡張子を除いたフルパスで登録
        /// </summary>
        [MenuItem(MENU_ITEM_ROOT + "FullPathWithoutExtension")]
        private static void SetterFullPathWithoutExtension()
        {
            Setter(AddressableNameMode.FullPathWithoutExtension);
        }

        /// <summary>
        /// 拡張子を除いたファイル名で登録
        /// </summary>
        [MenuItem(MENU_ITEM_ROOT + "FileNameWithoutExtension")]
        private static void SetterFileNameWithoutExtension()
        {
            Setter(AddressableNameMode.FileNameWithoutExtension);
        }

        /// <summary>
        /// 拡張子を除いた親フォルダ名とファイル名で登録
        /// </summary>
        [MenuItem(MENU_ITEM_ROOT + "ParentAndFileNameWithoutExtension")]
        private static void SetterParentAndFileNameWithoutExtension()
        {
            Setter(AddressableNameMode.ParentAndFileNameWithoutExtension);
        }

        /// <summary>
        /// アドレス登録
        /// </summary>
        private static void Setter(AddressableNameMode mode)
        {
            var selectionObjects = Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.DeepAssets);
            if (!selectionObjects.Any())
            {
                EditorUtility.DisplayDialog("エラー", "アセットかフォルダを選択して下さい\n(複数選択可)", "OK");
                return;
            }

            var settings = AddressableAssetSettingsDefaultObject.Settings;
            var defaultGroup = settings.DefaultGroup;
            var entryCount = 0;

            foreach ((var selectionObject, int index) in selectionObjects.Select((v, i) => (v, i)))
            {
                var assetPath = AssetDatabase.GetAssetPath(selectionObject);
                var progress = (float)index / selectionObjects.Length;
                EditorUtility.DisplayProgressBar("対象アセットチェック中・・・", assetPath, progress);

                if (!File.Exists(assetPath))
                {
                    continue;
                }

                var entry = CreateAddressableAssetEntry(settings, defaultGroup, assetPath);
                SetAddressableAsset(entry, assetPath, mode);
                entryCount++;
            }

            EditorUtility.ClearProgressBar();

            EditorUtility.DisplayDialog("報告", $"{entryCount}個のアセットの設定が完了しました", "OK");
        }

        /// <summary>
        /// グループ名を作成
        /// </summary>
        private static AddressableAssetGroup CreateAddressableAssetGroup(AddressableAssetSettings settings, string groupName)
        {
            var groupTemplate = settings.GetGroupTemplateObject(0) as AddressableAssetGroupTemplate;
            var group = settings.CreateGroup(groupName, false, false, true, null, groupTemplate.GetTypes());
            groupTemplate.ApplyToAddressableAssetGroup(group);
            return group;
        }

        /// <summary>
        /// AddressableAssetEntryを作成
        /// </summary>
        private static AddressableAssetEntry CreateAddressableAssetEntry(AddressableAssetSettings settings, AddressableAssetGroup group, string assetPath)
        {
            var guid = AssetDatabase.AssetPathToGUID(assetPath);
            var entry = settings.CreateOrMoveEntry(guid, group);
            return entry;
        }

        /// <summary>
        /// アセットに対してアドレスを設定
        /// </summary>
        private static void SetAddressableAsset(AddressableAssetEntry entry, string assetPath, AddressableNameMode mode, string label = null)
        {
            // パスの「\\」を「/」に変換
            assetPath = assetPath.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);

            switch (mode)
            {
                case AddressableNameMode.FullPath:
                    {
                        entry.SetAddress(assetPath);
                    }
                    break;
                case AddressableNameMode.FullPathWithoutExtension:
                    {
                        var ext = Path.GetExtension(assetPath);
                        var full = assetPath.Substring(0, assetPath.Length - ext.Length);
                        entry.SetAddress(full);
                    }
                    break;
                case AddressableNameMode.FileNameWithoutExtension:
                    {
                        var assetName = Path.GetFileNameWithoutExtension(assetPath);
                        entry.SetAddress(assetName);
                    }
                    break;
                case AddressableNameMode.ParentAndFileNameWithoutExtension:
                    {
                        var dir = Directory.GetParent(assetPath).Name;
                        var assetName = Path.GetFileNameWithoutExtension(assetPath);
                        entry.SetAddress($"{dir}/{assetName}");
                    }
                    break;
            }

            if (label != null)
            {
                entry.SetLabel(label, true);
            }
        }
    }
}

Discussion