private static string GetAddressName(string address, Type assetType, FieldInfo fieldInfo = null, bool forceFlatHierarchy = false)
        {
            string rootFolder = "";

            bool flatHierarchy = false;

            Type fieldType = fieldInfo.GetChildValueType();

            if (fieldType != null)
            {
                LinkFolderAttribute folderAttr = fieldType.GetCustomAttribute <LinkFolderAttribute>();

                FlatHierarchy flatHierarchyAttr = fieldType.GetCustomAttribute <FlatHierarchy>();

                if (flatHierarchyAttr == null)
                {
                    flatHierarchyAttr = assetType.GetCustomAttribute <FlatHierarchy>();
                }

                if (flatHierarchyAttr != null)
                {
                    flatHierarchy = true;
                }

                if (folderAttr != null)
                {
                    rootFolder += folderAttr.folder;
                }
            }

            if (typeof(ModuleConfig).IsAssignableFrom(assetType))
            {
                rootFolder = $"{Folders.Configs}";
            }

            if (typeof(BehaviourModule).IsAssignableFrom(assetType))
            {
                rootFolder = $"{Folders.Modules}";
            }

            AddrSingletonAttribute singletonAttr = assetType.GetCustomAttribute <AddrSingletonAttribute>();

            if (singletonAttr != null && fieldType != null)
            {
                address = fieldType.Name + " (Singleton)";
                return(address);
            }

            if (address.StartsWith(rootFolder))
            {
                address = address.Substring(rootFolder.Length, address.Length - rootFolder.Length).RemoveExtention();
            }

            if (address.StartsWith("/"))
            {
                address = address.Substring(1, address.Length - 1);
            }

            return(flatHierarchy || forceFlatHierarchy?Path.GetFileNameWithoutExtension(address) : address);
        }
        protected static string CreateAsset(Type type, Type linkType, FieldInfo fieldInfo)
        {
            LinkFolderAttribute folderAttr = linkType.GetCustomAttribute <LinkFolderAttribute>();
            string defaultFolder           = folderAttr != null ? ResourcesAssetHelper.RootFolder + "/" + folderAttr.folder : ResourcesAssetHelper.RootFolder;

            if (fieldInfo != null && fieldInfo.GetCustomAttribute <LinkFolderAttribute>() != null)
            {
                defaultFolder = ResourcesAssetHelper.RootFolder + "/" + fieldInfo.GetCustomAttribute <LinkFolderAttribute>().folder;
            }

            string ext = GetExtension(type);

            if (Directory.Exists(defaultFolder) == false)
            {
                Directory.CreateDirectory(defaultFolder);
            }

            string path = EditorUtility.SaveFilePanelInProject("Create new " + type.Name, fieldInfo?.Name.FirstCharToUpper(), ext, "Create new " + type.Name, defaultFolder);

            if (string.IsNullOrEmpty(path))
            {
                return(null);
            }

            if (ext == "prefab")
            {
                GameObject go = new GameObject(type.Name);
                go.AddComponent(type);
                PrefabUtility.SaveAsPrefabAsset(go, path);
                Object.DestroyImmediate(go);
            }
            else
            {
                ScriptableObject so = ScriptableObject.CreateInstance(type);
                AssetDatabase.CreateAsset(so, path);
            }

            string address = null;

#if USE_ADDRESSABLES
            AddrHelper.Reload();

            AddressableAssetEntry entry = AddrHelper.CreateOrModifyEntry(AssetDatabase.AssetPathToGUID(path));
            address = entry.address;
#else
            address = ResourcesAssetEntry.GetAddress(path);
#endif
            AssetDatabase.Refresh();

            return(address);
        }