Ejemplo n.º 1
0
        private static void OnPrefabStageOpened(PrefabStage stage)
        {
            Preview p = stage.prefabContentsRoot.GetComponentInChildren <Preview>();

            if (p)
            {
                p.GenerateIcon();

                Debug.Log("Creating preview for weapon " + stage.prefabContentsRoot.name);

                AddressableAssetSettings settings = AddressableAssetSettingsDefaultObject.Settings;

                if (settings != null)
                {
                    string prefabGuid = AssetDatabase.AssetPathToGUID(stage.prefabAssetPath);
                    AddressableAssetEntry prefabEntry = settings.FindAssetEntry(prefabGuid);

                    if (prefabEntry == null)
                    {
                        Debug.LogError("Prefab entry not found for prefab " + stage.prefabAssetPath);
                        return;
                    }
                }
            }
            else
            {
                Debug.LogError("Preview component not found on weapon " + stage.prefabContentsRoot.name + ". Please make sure your prefab contains a Preview Script on a children GameObject.");
            }

            stage.ClearDirtiness();
            PrefabStage.prefabStageOpened -= OnPrefabStageOpened;
        }
Ejemplo n.º 2
0
        internal static List <TargetInfo> GatherTargetInfos(Object[] targets, AddressableAssetSettings aaSettings)
        {
            var targetInfos = new List <TargetInfo>();
            AddressableAssetEntry entry;

            foreach (var t in targets)
            {
                if (AddressableAssetUtility.TryGetPathAndGUIDFromTarget(t, out var path, out var guid))
                {
                    var mainAssetType = AssetDatabase.GetMainAssetTypeAtPath(path);
                    // Is asset
                    if (mainAssetType != null && !BuildUtility.IsEditorAssembly(mainAssetType.Assembly))
                    {
                        bool isMainAsset = t is AssetImporter || AssetDatabase.IsMainAsset(t);
                        var  info        = new TargetInfo()
                        {
                            TargetObject = t, Guid = guid, Path = path, IsMainAsset = isMainAsset
                        };

                        if (aaSettings != null)
                        {
                            entry = aaSettings.FindAssetEntry(guid, true);
                            if (entry != null)
                            {
                                info.MainAssetEntry = entry;
                            }
                        }

                        targetInfos.Add(info);
                    }
                }
            }

            return(targetInfos);
        }
Ejemplo n.º 3
0
        static List <AddressableAssetEntry> SetEntries(AddressableAssetSettings aaSettings, Object[] targets)
        {
            if (aaSettings.DefaultGroup.ReadOnly)
            {
                Debug.LogError("Current default group is ReadOnly.  Cannot add addressable assets to it");
                return(null);
            }

            Undo.RecordObject(aaSettings, "AddressableAssetSettings");
            string path;
            var    guid = string.Empty;

            var entriesAdded = new List <AddressableAssetEntry>();
            var result       = new List <AddressableAssetEntry>();

            var modifiedGroups = new HashSet <AddressableAssetGroup>();

            AddressableAssetGroup modified = new AddressableAssetGroup();

            Type mainAssetType;

            foreach (var o in targets)
            {
                if (AddressableAssetUtility.GetPathAndGUIDFromTarget(o, out path, ref guid, out mainAssetType))
                {
                    var entry = aaSettings.FindAssetEntry(guid);
                    if (entry == null)
                    {
                        if (AddressableAssetUtility.IsInResources(path))
                        {
                            AddressableAssetUtility.SafeMoveResourcesToGroup(aaSettings, aaSettings.DefaultGroup, new List <string> {
                                path
                            });
                        }
                        else
                        {
                            var e = aaSettings.CreateOrMoveEntry(guid, aaSettings.DefaultGroup, false, false);
                            entriesAdded.Add(e);
                            modifiedGroups.Add(e.parentGroup);
                        }
                    }
                    else
                    {
                        result.Add(entry);
                    }
                }
            }

            foreach (var g in modifiedGroups)
            {
                g.SetDirty(AddressableAssetSettings.ModificationEvent.EntryMoved, entriesAdded, false, true);
            }

            aaSettings.SetDirty(AddressableAssetSettings.ModificationEvent.EntryMoved, entriesAdded, true, false);

            result.AddRange(entriesAdded);

            return(result);
        }
Ejemplo n.º 4
0
        static void SetAaEntry(AddressableAssetSettings aaSettings, Object[] targets, bool create)
        {
            if (create && aaSettings.DefaultGroup.ReadOnly)
            {
                Debug.LogError("Current default group is ReadOnly.  Cannot add addressable assets to it");
                return;
            }

            Undo.RecordObject(aaSettings, "AddressableAssetSettings");

            var targetInfos = new List <TargetInfo>();

            foreach (var t in targets)
            {
                if (AddressableAssetUtility.GetPathAndGUIDFromTarget(t, out var path, out var guid, out var mainAssetType))
                {
                    targetInfos.Add(new TargetInfo()
                    {
                        Guid = guid, Path = path, MainAssetType = mainAssetType
                    });
                }
            }

            if (!create)
            {
                targetInfos.ForEach(ti =>
                {
                    AddressableAssetGroup group = aaSettings.FindAssetEntry(ti.Guid).parentGroup;
                    aaSettings.RemoveAssetEntry(ti.Guid);
                    AddressableAssetUtility.OpenAssetIfUsingVCIntegration(group);
                });
            }
            else
            {
                var resourceTargets = targetInfos.Where(ti => AddressableAssetUtility.IsInResources(ti.Path));
                var resourcePaths   = resourceTargets.Select(t => t.Path).ToList();
                var resourceGuids   = resourceTargets.Select(t => t.Guid).ToList();
                AddressableAssetUtility.SafeMoveResourcesToGroup(aaSettings, aaSettings.DefaultGroup, resourcePaths, resourceGuids);

                var entriesAdded     = new List <AddressableAssetEntry>();
                var modifiedGroups   = new HashSet <AddressableAssetGroup>();
                var otherTargetInfos = targetInfos.Except(resourceTargets);
                foreach (var info in otherTargetInfos)
                {
                    var e = aaSettings.CreateOrMoveEntry(info.Guid, aaSettings.DefaultGroup, false, false);
                    entriesAdded.Add(e);
                    modifiedGroups.Add(e.parentGroup);
                }

                foreach (var g in modifiedGroups)
                {
                    g.SetDirty(AddressableAssetSettings.ModificationEvent.EntryMoved, entriesAdded, false, true);
                    AddressableAssetUtility.OpenAssetIfUsingVCIntegration(g);
                }

                aaSettings.SetDirty(AddressableAssetSettings.ModificationEvent.EntryMoved, entriesAdded, true, false);
            }
        }
Ejemplo n.º 5
0
    static void SetObjectAddressable(Object go, string guid)
    {
        AddressableAssetSettings aaSettings = AddressableAssetSettingsDefaultObject.Settings;
        AddressableAssetGroup    group      = aaSettings.DefaultGroup;
        AddressableAssetEntry    entry      = aaSettings.FindAssetEntry(guid);

        if (entry == null)
        {
            entry = aaSettings.CreateOrMoveEntry(guid, group, readOnly: false, postEvent: false);
        }
    }
        internal static void GetStaticContentDependenciesForEntries(AddressableAssetSettings settings, ref Dictionary <AddressableAssetEntry, List <AddressableAssetEntry> > dependencyMap, AddressablesContentState cacheData = null)
        {
            Dictionary <AddressableAssetGroup, bool> groupHasStaticContentMap = new Dictionary <AddressableAssetGroup, bool>();

            if (dependencyMap == null)
            {
                return;
            }

            HashSet <string> groupGuidsWithUnchangedBundleName = GetGroupGuidsWithUnchangedBundleName(settings, dependencyMap, cacheData);

            foreach (AddressableAssetEntry entry in dependencyMap.Keys)
            {
                //since the entry here is from our list of modified entries we know that it must be a part of a static content group.
                //Since it's part of a static content update group we can go ahead and set the value to true in the dictionary without explicitly checking it.
                if (!groupHasStaticContentMap.ContainsKey(entry.parentGroup))
                {
                    groupHasStaticContentMap.Add(entry.parentGroup, true);
                }

                string[] dependencies = AssetDatabase.GetDependencies(entry.AssetPath);
                foreach (string dependency in dependencies)
                {
                    string guid     = AssetDatabase.AssetPathToGUID(dependency);
                    var    depEntry = settings.FindAssetEntry(guid);
                    if (depEntry == null)
                    {
                        continue;
                    }

                    if (!groupHasStaticContentMap.TryGetValue(depEntry.parentGroup, out bool groupHasStaticContentEnabled))
                    {
                        groupHasStaticContentEnabled = depEntry.parentGroup.HasSchema <ContentUpdateGroupSchema>() &&
                                                       depEntry.parentGroup.GetSchema <ContentUpdateGroupSchema>().StaticContent;

                        if (groupGuidsWithUnchangedBundleName.Contains(depEntry.parentGroup.Guid))
                        {
                            continue;
                        }

                        groupHasStaticContentMap.Add(depEntry.parentGroup, groupHasStaticContentEnabled);
                    }

                    if (!dependencyMap.ContainsKey(depEntry) && groupHasStaticContentEnabled)
                    {
                        if (!dependencyMap.ContainsKey(entry))
                        {
                            dependencyMap.Add(entry, new List <AddressableAssetEntry>());
                        }
                        dependencyMap[entry].Add(depEntry);
                    }
                }
            }
        }
Ejemplo n.º 7
0
        public static AssetReference SetObjectAddressable(Object go)
        {
            string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(go));
            AddressableAssetSettings aaSettings = AddressableAssetSettingsDefaultObject.Settings;
            AddressableAssetGroup    group      = aaSettings.DefaultGroup;
            AddressableAssetEntry    entry      = aaSettings.FindAssetEntry(guid);

            if (entry == null)
            {
                entry = aaSettings.CreateOrMoveEntry(guid, group, readOnly: false, postEvent: false);
            }
            return(new AssetReference(guid));
        }
        /// <summary>
        /// Find the addressable asset entry for the given asset in these settings.
        /// </summary>
        /// <param name="s">The settings containing the groups for which to fetch the asset entry.</param>
        /// <param name="asset">The asset for which to find the addressable asset entry in the settings.</param>
        /// <returns>The entry in the settings, null otherwise.</returns>
        public static AddressableAssetEntry FindAssetEntry(this AddressableAssetSettings s, UnityEngine.Object asset)
        {
            s.ThrowIfNull(nameof(s));
            asset.ThrowIfNull(nameof(asset));
            string assetGuid = GetAssetGuid(asset);

            if (string.IsNullOrWhiteSpace(assetGuid))
            {
                return(null);
            }

            return(s.FindAssetEntry(assetGuid));
        }
Ejemplo n.º 9
0
        internal static void MoveAssetsFromResources(Dictionary <string, string> guidToNewPath, AddressableAssetGroup targetParent, AddressableAssetSettings settings)
        {
            if (guidToNewPath == null)
            {
                return;
            }
            var entries = new List <AddressableAssetEntry>();

            AssetDatabase.StartAssetEditing();
            foreach (var item in guidToNewPath)
            {
                var dirInfo = new FileInfo(item.Value).Directory;
                if (dirInfo != null && !dirInfo.Exists)
                {
                    dirInfo.Create();
                    AssetDatabase.StopAssetEditing();
                    AssetDatabase.Refresh();
                    AssetDatabase.StartAssetEditing();
                }

                var oldPath  = AssetDatabase.GUIDToAssetPath(item.Key);
                var errorStr = AssetDatabase.MoveAsset(oldPath, item.Value);
                if (!string.IsNullOrEmpty(errorStr))
                {
                    DebugUtility.LogError(LoggerTags.Engine, "Error moving asset:{0} ", errorStr);
                }
                else
                {
                    AddressableAssetEntry e = settings.FindAssetEntry(item.Key);
                    if (e != null)
                    {
                        e.IsInResources = false;
                    }

                    var newEntry = settings.CreateOrMoveEntry(item.Key, targetParent, false, false);
                    var index    = oldPath.ToLower().LastIndexOf("resources/");
                    if (index >= 0)
                    {
                        var newAddress = Path.GetFileNameWithoutExtension(oldPath.Substring(index + 10));
                        if (!string.IsNullOrEmpty(newAddress))
                        {
                            newEntry.address = newAddress;
                        }
                    }
                    entries.Add(newEntry);
                }
            }
            AssetDatabase.StopAssetEditing();
            AssetDatabase.Refresh();
            settings.SetDirty(AddressableAssetSettings.ModificationEvent.EntryMoved, entries, true, true);
        }
Ejemplo n.º 10
0
        public void UpdateEntry(string assetGuid, string address = null, string[] labels = null)
        {
            var entry = _settings.FindAssetEntry(assetGuid);

            if (entry == null)
            {
                throw new Exception(
                          $"Failed to get {nameof(AddressableAssetEntry)} (GUID:{assetGuid}) because it does not exists.");
            }

            if (address != null)
            {
                entry.SetAddress(address);
            }

            if (labels != null)
            {
                entry.labels.Clear();
                foreach (var label in labels)
                {
                    entry.SetLabel(label, true, true);
                }
            }
        }
Ejemplo n.º 11
0
    void OnWizardCreate()
    {
        //save/update any editor prefs we have changed
        EditorPrefs.SetString("ARW_append", append);
        EditorPrefs.SetString("ARW_search", search);
        EditorPrefs.SetString("ARW_replace", replace);

        string[] assetGUIDs = Selection.assetGUIDs;
        if (assetGUIDs != null)
        {
            AddressableAssetSettings settings = AddressableAssetSettingsDefaultObject.Settings;
            if (settings == null)
            {
                Debug.LogError("Could not find AddressableAssetSettings!");
                return;
            }

            var entries = new List <AddressableAssetEntry>();
            foreach (string assetGUID in assetGUIDs)
            {
                AddressableAssetEntry entry = settings.FindAssetEntry(assetGUID);
                if (entry != null)
                {
                    string newAddress = append + entry.address;
                    if (!string.IsNullOrEmpty(search))
                    {
                        newAddress = newAddress.Replace(search, replace);
                    }
                    entry.SetAddress(newAddress, false);
                    entries.Add(entry);
                }
                else
                {
                    string assetPath = AssetDatabase.GUIDToAssetPath(assetGUID);
                    if (string.IsNullOrEmpty(assetPath))
                    {
                        Debug.LogWarning(assetGUID + " is not marked as Addressable.");
                    }
                    else
                    {
                        Debug.LogWarning(assetPath + " is not marked as Addressable.");
                    }
                }
            }

            settings.SetDirty(AddressableAssetSettings.ModificationEvent.EntryModified, entries, true, false);
        }
    }
Ejemplo n.º 12
0
    /// <summary>
    /// 为指定的资源创建相应的组
    /// </summary>
    /// <param name="assetPath"></param>
    /// <param name="setting"></param>
    /// <param name="groupTemplete"></param>
    /// <returns></returns>
    static AddressableAssetEntry CreateGroupForAsset(string assetPath, AddressableAssetSettings setting, AddressableAssetGroupTemplate groupTemplete)
    {
        string guid  = AssetDatabase.AssetPathToGUID(assetPath);
        var    entry = setting.FindAssetEntry(guid);

        if (entry != null)
        {
            var group = entry.parentGroup;
            groupTemplete.ApplyToAddressableAssetGroup(group);
        }
        else
        {
            entry = CreateEntryToNewGroup(setting, groupTemplete, assetPath);
        }
        return(entry);
    }
Ejemplo n.º 13
0
        public static AddressableAssetEntry GetOrCreateEntry(Object o)
        {
            AddressableAssetSettings aaSettings = AddressableAssetSettingsDefaultObject.Settings;
            AddressableAssetEntry    entry      = null;
            bool foundAsset = AssetDatabase.TryGetGUIDAndLocalFileIdentifier(o, out var guid, out long _);
            var  path       = AssetDatabase.GUIDToAssetPath(guid);

            if (foundAsset && (path.ToLower().Contains("assets")))
            {
                if (aaSettings != null)
                {
                    entry = aaSettings.FindAssetEntry(guid);
                }
            }
            if (entry != null)
            {
                return(entry);
            }
            entry = aaSettings.CreateOrMoveEntry(guid, aaSettings.DefaultGroup);
            return(entry);
        }
Ejemplo n.º 14
0
    /// <summary>
    /// 创新新的资源条目,并将添加到新的组中
    /// </summary>
    /// <param name="setting"></param>
    /// <param name="groupTemplete"></param>
    /// <param name="assetPath"></param>
    /// <returns></returns>
    static AddressableAssetEntry CreateEntryToNewGroup(AddressableAssetSettings setting, AddressableAssetGroupTemplate groupTemplete, string assetPath)
    {
        string guid  = AssetDatabase.AssetPathToGUID(assetPath);
        var    entry = setting.FindAssetEntry(guid);

        if (entry != null)
        {
            return(entry);
        }

        var newGroup = setting.CreateGroup(assetPath, false, false, true, null, groupTemplete.GetTypes());

        groupTemplete.ApplyToAddressableAssetGroup(newGroup);

        var entryToAdd = setting.CreateOrMoveEntry(guid, newGroup, false, false);

        newGroup.SetDirty(AddressableAssetSettings.ModificationEvent.EntryMoved, entryToAdd, false, true);
        setting.SetDirty(AddressableAssetSettings.ModificationEvent.EntryMoved, entryToAdd, true, false);

        return(entryToAdd);
    }
Ejemplo n.º 15
0
        internal void DragAndDropNotFromAddressableGroupWindow(string path, string guid, SerializedProperty property, AddressableAssetSettings aaSettings)
        {
            if (AddressableAssetUtility.IsInResources(path))
            {
                Addressables.LogWarning("Cannot use an AssetReference on an asset in Resources. Move asset out of Resources first. ");
            }
            else if (!AddressableAssetUtility.IsPathValidForEntry(path))
            {
                Addressables.LogWarning("Dragged asset is not valid as an Asset Reference. " + path);
            }
            else
            {
                Object obj;
                if (DragAndDrop.objectReferences != null && DragAndDrop.objectReferences.Length == 1)
                {
                    obj = DragAndDrop.objectReferences[0];
                }
                else
                {
                    obj = AssetDatabase.LoadAssetAtPath <Object>(path);
                }

                if (AssetReferenceDrawerUtilities.SetObject(ref m_AssetRefObject, ref m_ReferencesSame, property, obj, fieldInfo, m_label.text, out guid))
                {
                    TriggerOnValidate(property);
                    aaSettings = AddressableAssetSettingsDefaultObject.GetSettings(true);
                    var entry = aaSettings.FindAssetEntry(guid);
                    if (entry == null && !string.IsNullOrEmpty(guid))
                    {
                        string assetName;
                        if (!aaSettings.IsAssetPathInAddressableDirectory(path, out assetName))
                        {
                            aaSettings.CreateOrMoveEntry(guid, aaSettings.DefaultGroup);
                            newGuid = guid;
                        }
                    }
                }
            }
        }
Ejemplo n.º 16
0
        public void GenerateIcon()
        {
            Dictionary <Renderer, int> dicRenderers = new Dictionary <Renderer, int>();

            if (renderers.Count == 0)
            {
                foreach (Renderer renderer in (renderers.Count == 0 ? new List <Renderer>(this.transform.root.GetComponentsInChildren <Renderer>()) : renderers))
                {
                    dicRenderers.Add(renderer, renderer.gameObject.layer);
                    renderer.gameObject.layer = tempLayer;
                }
            }

            Camera cam = new GameObject().AddComponent <Camera>();

            cam.transform.SetParent(this.transform);
            cam.orthographic     = true;
            cam.targetTexture    = RenderTexture.GetTemporary(iconResolution, iconResolution, 16);
            cam.clearFlags       = CameraClearFlags.Color;
            cam.stereoTargetEye  = StereoTargetEyeMask.None;
            cam.orthographicSize = size / 2;
            cam.cullingMask      = 1 << tempLayer;
            cam.enabled          = false;

            cam.transform.position = this.transform.position + (this.transform.forward * -1);
            cam.transform.rotation = this.transform.rotation;
            Light camLight = cam.gameObject.AddComponent <Light>();

            camLight.transform.SetParent(cam.transform);
            camLight.type    = LightType.Directional;
            camLight.enabled = true;


            string iconPath = null;

            if (PrefabStageUtility.GetCurrentPrefabStage() != null)
            {
                // Prefab editor
                iconPath  = PrefabStageUtility.GetCurrentPrefabStage().prefabAssetPath;
                cam.scene = PrefabStageUtility.GetCurrentPrefabStage().scene;
            }
            else if (PrefabUtility.GetNearestPrefabInstanceRoot(this))
            {
                // Prefab in scene
                iconPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(this);
            }
            else
            {
                // Not a prefab
                Debug.LogError("Unable to create an icon file if the object is not a prefab!");
            }

            cam.Render();

            RenderTexture orgActiveRenderTexture = RenderTexture.active;

            RenderTexture.active = cam.targetTexture;

            generatedIcon = new Texture2D(cam.targetTexture.width, cam.targetTexture.height, TextureFormat.ARGB32, false);
            generatedIcon.ReadPixels(new Rect(0, 0, cam.targetTexture.width, cam.targetTexture.height), 0, 0);
            generatedIcon.Apply(false);

            RenderTexture.active = orgActiveRenderTexture;

            // Clean up after ourselves
            cam.targetTexture = null;
            RenderTexture.ReleaseTemporary(cam.targetTexture);

            foreach (KeyValuePair <Renderer, int> renderer in dicRenderers)
            {
                renderer.Key.gameObject.layer = renderer.Value;
            }

            DestroyImmediate(cam.gameObject);

            if (iconPath != null)
            {
                byte[] bytes = generatedIcon.EncodeToPNG();
                string path  = iconPath.Replace(".prefab", ".png");
                System.IO.File.WriteAllBytes(path, bytes);
                AssetDatabase.Refresh();
                generatedIcon = AssetDatabase.LoadAssetAtPath <Texture2D>(path);
                TextureImporter textureImporter = (TextureImporter)TextureImporter.GetAtPath(path);
                textureImporter.alphaIsTransparency = true;
                EditorUtility.SetDirty(textureImporter);
                textureImporter.SaveAndReimport();
                Debug.Log("Icon generated : " + path);

                AddressableAssetSettings settings = AddressableAssetSettingsDefaultObject.Settings;
                if (settings != null)
                {
                    string guid = AssetDatabase.AssetPathToGUID(path);
                    AddressableAssetEntry entry = settings.FindAssetEntry(guid);

                    if (entry == null)
                    {
                        Debug.Log("Added icon to addressable");
                        entry = settings.CreateOrMoveEntry(guid, settings.DefaultGroup);
                        settings.SetDirty(AddressableAssetSettings.ModificationEvent.EntryAdded, entry, true, false);
                    }

                    string prefabGuid = AssetDatabase.AssetPathToGUID(iconPath);
                    AddressableAssetEntry prefabEntry = settings.FindAssetEntry(prefabGuid);

                    if (prefabEntry != null)
                    {
                        entry.SetAddress(prefabEntry.address + ".Icon", false);
                    }
                }
                else
                {
                    Debug.LogError("Could not find AddressableAssetSettings, cannot set the icon to addressable");
                    return;
                }
            }
        }
        /// <summary>
        /// Find the addressable asset group to which the asset belongs to, provided it is registered as an addressable asset.
        /// </summary>
        /// <param name="s">The settings containing the groups for which to find the asset group the asset belongs to.</param>
        /// <param name="asset">The asset for which to find the asset group it belongs to.</param>
        /// <returns>The group in the settings, null otherwise.</returns>
        public static AddressableAssetGroup FindAssetGroup(this AddressableAssetSettings s, UnityEngine.Object asset)
        {
            AddressableAssetEntry entry = s.FindAssetEntry(asset);

            return((entry != null) ? entry.parentGroup : null);
        }
 /// <summary>
 /// Is the asset registered as an addressable asset with these settings?
 /// </summary>
 /// <param name="s">The settings containing the groups for which to check the asset.</param>
 /// <param name="asset">The asset to check whether it is an addressable asset or not.</param>
 /// <returns>True if the asset is a registered asset, false otherwise.</returns>
 public static bool IsAssetAddressable(this AddressableAssetSettings s, UnityEngine.Object asset)
 {
     return(s.FindAssetEntry(asset) != null);
 }
        static void SetAaEntry(AddressableAssetSettings aaSettings, List <TargetInfo> targetInfos, bool create)
        {
            if (create && aaSettings.DefaultGroup.ReadOnly)
            {
                Debug.LogError("Current default group is ReadOnly.  Cannot add addressable assets to it");
                return;
            }

            Undo.RecordObject(aaSettings, "AddressableAssetSettings");

            if (!create)
            {
                List <AddressableAssetEntry> removedEntries = new List <AddressableAssetEntry>(targetInfos.Count);
                for (int i = 0; i < targetInfos.Count; ++i)
                {
                    AddressableAssetEntry e = aaSettings.FindAssetEntry(targetInfos[i].Guid);
                    AddressableAssetUtility.OpenAssetIfUsingVCIntegration(e.parentGroup);
                    removedEntries.Add(e);
                    aaSettings.RemoveAssetEntry(removedEntries[i], false);
                }
                if (removedEntries.Count > 0)
                {
                    aaSettings.SetDirty(AddressableAssetSettings.ModificationEvent.EntryRemoved, removedEntries, true, false);
                }
            }
            else
            {
                AddressableAssetGroup parentGroup = aaSettings.DefaultGroup;
                var resourceTargets = targetInfos.Where(ti => AddressableAssetUtility.IsInResources(ti.Path));
                if (resourceTargets.Any())
                {
                    var resourcePaths = resourceTargets.Select(t => t.Path).ToList();
                    var resourceGuids = resourceTargets.Select(t => t.Guid).ToList();
                    AddressableAssetUtility.SafeMoveResourcesToGroup(aaSettings, parentGroup, resourcePaths, resourceGuids);
                }

                var           otherTargetInfos = targetInfos.Except(resourceTargets);
                List <string> otherTargetGuids = new List <string>(targetInfos.Count);
                foreach (var info in otherTargetInfos)
                {
                    otherTargetGuids.Add(info.Guid);
                }

                var entriesCreated = new List <AddressableAssetEntry>();
                var entriesMoved   = new List <AddressableAssetEntry>();
                aaSettings.CreateOrMoveEntries(otherTargetGuids, parentGroup, entriesCreated, entriesMoved, false, false);

                bool openedInVC = false;
                if (entriesMoved.Count > 0)
                {
                    AddressableAssetUtility.OpenAssetIfUsingVCIntegration(parentGroup);
                    openedInVC = true;
                    aaSettings.SetDirty(AddressableAssetSettings.ModificationEvent.EntryMoved, entriesMoved, true, false);
                }

                if (entriesCreated.Count > 0)
                {
                    if (!openedInVC)
                    {
                        AddressableAssetUtility.OpenAssetIfUsingVCIntegration(parentGroup);
                    }
                    aaSettings.SetDirty(AddressableAssetSettings.ModificationEvent.EntryAdded, entriesCreated, true, false);
                }
            }
        }
        protected virtual void Analyze(AddressableAssetSettings settings, GroupResolver resolver)
        {
            try
            {
                EditorUtility.DisplayProgressBar(ruleName, "Finding Tables", 0);
                var tables = AssetDatabase.FindAssets($"t:{typeof(TTable).Name}");

                // Collate the groups so we can check them at the end.
                var groups = new HashSet <AddressableAssetGroup>();

                for (var i = 0; i < tables.Length; ++i)
                {
                    var progress = i / (float)tables.Length;

                    var guid  = tables[i];
                    var entry = settings.FindAssetEntry(guid);
                    var path  = AssetDatabase.GUIDToAssetPath(guid);
                    var table = AssetDatabase.LoadAssetAtPath <TTable>(path);
                    var label = $"{table} - {path}";

                    EditorUtility.DisplayProgressBar(ruleName, $"Checking Table {path}", progress);

                    var collection = LocalizationEditorSettings.GetCollectionForSharedTableData(table.SharedData);
                    if (collection == null)
                    {
                        m_Results.Add(new TableResult
                        {
                            resultName = $"{table} - {path}:Loose Table.",
                            severity   = MessageType.Info,
                            // TODO: Create collection for it?
                        });
                        continue;
                    }

                    CheckContents(table, label, settings, collection);

                    if (entry == null)
                    {
                        m_Results.Add(new TableResult
                        {
                            resultName = $"{label}:Not Marked as Addressable",
                            severity   = MessageType.Error,
                            FixAction  = () =>
                            {
                                collection.AddTable(table);
                                collection.AddSharedTableDataToAddressables();
                            }
                        });
                        continue;
                    }

                    groups.Add(entry.parentGroup);

                    // Group Name
                    var groupName = resolver.GetExpectedGroupName(new[] { table.LocaleIdentifier }, table, settings);
                    if (entry.parentGroup.Name != groupName)
                    {
                        m_Results.Add(new TableResult
                        {
                            resultName = $"{label}:Incorrect Group:Expected `{groupName}` but was `{entry.parentGroup.Name}`",
                            severity   = MessageType.Warning,
                            FixAction  = () => resolver.AddToGroup(table, new[] { table.LocaleIdentifier }, settings, false)
                        });
                    }

                    // Label
                    var expectedLabel = AddressHelper.FormatAssetLabel(table.LocaleIdentifier);
                    if (!entry.labels.Contains(expectedLabel))
                    {
                        m_Results.Add(new TableResult
                        {
                            resultName = $"{label}:Missing Locale label.",
                            severity   = MessageType.Warning,
                            FixAction  = () => entry.SetLabel(expectedLabel, true, true)
                        });
                    }

                    // Address
                    var expectedAddress = AddressHelper.GetTableAddress(table.TableCollectionName, table.LocaleIdentifier);
                    if (!entry.labels.Contains(expectedLabel))
                    {
                        m_Results.Add(new TableResult
                        {
                            resultName = $"{label}:Incorrect Address:Expected `{expectedAddress}` but was `{entry.address}`",
                            severity   = MessageType.Error,
                            FixAction  = () => entry.address = expectedAddress
                        });
                    }

                    // Shared Table Data
                    var sharedGuid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(table.SharedData));
                    var g          = new Guid(sharedGuid);
                    if (table.SharedData.TableCollectionNameGuid != g)
                    {
                        m_Results.Add(new TableResult
                        {
                            resultName = $"{label}:Incorrect Shared Table Guid:Expected {g} but was {table.SharedData.TableCollectionNameGuid}",
                            severity   = MessageType.Error,
                            FixAction  = () =>
                            {
                                table.SharedData.TableCollectionNameGuid = g;
                                EditorUtility.SetDirty(table.SharedData);
                            }
                        });
                    }

                    var sharedEntry = settings.FindAssetEntry(sharedGuid);
                    if (sharedEntry == null)
                    {
                        m_Results.Add(new TableResult
                        {
                            resultName = $"{label}:Shared Table Not Marked as Addressable",
                            severity   = MessageType.Warning,
                            FixAction  = () => resolver.AddToGroup(table.SharedData, null, settings, false)
                        });
                        continue;
                    }

                    groups.Add(sharedEntry.parentGroup);

                    // Shared Group Name
                    var sharedGroupName = resolver.GetExpectedGroupName(null, table.SharedData, settings);
                    if (sharedEntry.parentGroup.Name != sharedGroupName)
                    {
                        m_Results.Add(new TableResult
                        {
                            resultName = $"{label}:Incorrect Shared Table Data Group:Expected `{sharedGroupName}` but was `{sharedEntry.parentGroup.Name}`",
                            severity   = MessageType.Warning,
                            FixAction  = () => resolver.AddToGroup(table.SharedData, null, settings, false)
                        });
                    }

                    var expectedSharedGroupName = resolver.GetExpectedGroupName(null, table.SharedData, settings);
                    if (sharedEntry.parentGroup.Name != expectedSharedGroupName)
                    {
                        m_Results.Add(new TableResult
                        {
                            resultName = $"{label}:Incorrect Group:Expected `{expectedSharedGroupName}` but was `{sharedEntry.parentGroup.Name}`",
                            severity   = MessageType.Warning,
                            FixAction  = () => resolver.AddToGroup(table.SharedData, null, settings, false)
                        });
                    }
                }

                if (groups.Count > 0)
                {
                    foreach (var g in groups)
                    {
                        if (g.Schemas.Count == 0 || g.Schemas.All(s => s == null))
                        {
                            m_Results.Add(new TableResult
                            {
                                resultName = $"{g.Name}:Addressables Group Contains No Schemas",
                                severity   = MessageType.Error,
                                FixAction  = () =>
                                {
                                    g.AddSchema <BundledAssetGroupSchema>();
                                    g.AddSchema <ContentUpdateGroupSchema>();
                                }
                            });
                        }
                    }
                }
            }
            finally
            {
                EditorUtility.ClearProgressBar();
            }
        }
Ejemplo n.º 21
0
        public override List <AnalyzeResult> RefreshAnalysis(AddressableAssetSettings settings)
        {
            List <AnalyzeResult> results = new List <AnalyzeResult>();

            ClearAnalysis();
            ClearOurData();

            var projectRoot = Application.dataPath.Substring(0, Application.dataPath.Length - "Assets/".Length);

            if (!BuildUtility.CheckModifiedScenesAndAskToSave())
            {
                Debug.LogError("Cannot run Analyze with unsaved scenes");
                results.Add(new AnalyzeResult {
                    resultName = ruleName + "Cannot run Analyze with unsaved scenes"
                });
                return(results);
            }

            // Get all immediate folders in Assets/AutoBundles

            HashSet <string> folderNames = new HashSet <string>();
            var folders = AssetDatabase.GetSubFolders("Assets/" + autoBundlesFolderName);

            foreach (var folder in folders)
            {
                folderNames.Add(Path.GetFileName(folder));
            }

            // Get all addressable groups carrying the (Auto) prefix

            HashSet <string> autoGroups = new HashSet <string>();

            foreach (var group in settings.groups)
            {
                if (group.name.StartsWith(autoGroupPrefix))
                {
                    autoGroups.Add(group.name);
                }
            }

            // Collect all groups that must be created or moved

            foreach (var folder in folderNames)
            {
                var autoName = autoGroupPrefix + folder;
                if (!autoGroups.Contains(autoName))
                {
                    groupsToCreate.Add(autoName);
                    results.Add(new AnalyzeResult()
                    {
                        resultName = "Create group \"" + autoName + "\""
                    });
                }
            }

            // Collect all groups that must be removed

            foreach (var groupName in autoGroups)
            {
                var baseName = groupName.Substring(autoGroupPrefix.Length);
                if (!folderNames.Contains(baseName))
                {
                    groupsToRemove.Add(groupName);
                    results.Add(new AnalyzeResult()
                    {
                        resultName = "Remove group \"" + groupName + "\""
                    });
                }
            }

            // Get all assets

            var allGuids    = AssetDatabase.FindAssets(assetFilter, new [] { "Assets/" + autoBundlesFolderName });
            var neverBundle = new HashSet <string>();

            // Only include assets that pass basic filtering, like file extension.
            // Result is "assetPaths", the authoritative list of assets we're considering bundling.

            var assetPaths = new HashSet <string>();

            foreach (var guid in allGuids)
            {
                var path = AssetDatabase.GUIDToAssetPath(guid);

                if (ShouldIgnoreAsset(path))
                {
                    neverBundle.Add(path.ToLower());
                }
                else
                {
                    assetPaths.Add(path);
                }
            }

            // Collect all parents of all assets in preparation for not bundling assets with one ultimate non-scene parent.

            var parents = new Dictionary <string, HashSet <string> >(); // Map from asset guid to all its parents

            foreach (var path in assetPaths)
            {
                var dependencies = AssetDatabase.GetDependencies(path);

                foreach (var asset in dependencies)
                {
                    if (asset == path)
                    {
                        // Ignore self
                        continue;
                    }

                    if (ShouldIgnoreAsset(asset))
                    {
                        continue;
                    }

                    if (!parents.ContainsKey(asset))
                    {
                        parents.Add(asset, new HashSet <string>());
                    }
                    parents[asset].Add(path);
                }
            }

            // Unbundle assets with zero parents

            foreach (var asset in assetPaths)
            {
                if (!parents.ContainsKey(asset))
                {
                    neverBundle.Add(asset.ToLower());
                }
            }

            Debug.Log(neverBundle.Count + " asset have zero parents and won't be bundled");
            int floor = neverBundle.Count;

            // Unbundle assets with one parent

            foreach (var asset in assetPaths)
            {
                if (parents.ContainsKey(asset) && parents[asset].Count == 1)
                {
                    neverBundle.Add(asset.ToLower());
                }
            }

            Debug.Log((neverBundle.Count - floor) + " asset have one parent and won't be bundled");
            floor = neverBundle.Count;

            // Unbundle assets with one ultimate parent

            var ultimateParents = new Dictionary <string, HashSet <string> >();

            foreach (var asset in assetPaths)
            {
                if (neverBundle.Contains(asset.ToLower()))
                {
                    continue;
                }

                ultimateParents[asset] = new HashSet <string>();

                // Iterate all the way to the top for this asset. Assemble a list of all ultimate parents of this asset.

                var parentsToCheck = new List <string>();
                parentsToCheck.AddRange(parents[asset].ToList());

                while (parentsToCheck.Count != 0)
                {
                    var checking = parentsToCheck[0];
                    parentsToCheck.RemoveAt(0);

                    if (!parents.ContainsKey(checking))
                    {
                        // If asset we're checking doesn't itself have any parents, this is the end.
                        ultimateParents[asset].Add(checking);
                    }
                    else
                    {
                        parentsToCheck.AddRange(parents[checking]);
                    }
                }
            }

            // Unbundle all assets that don't have two or more required objects as ultimate parents.
            // Objects with one included parent will still get included if needed, just not as a separate Addressable.

            foreach (KeyValuePair <string, HashSet <string> > pair in ultimateParents)
            {
                int requiredParents = 0;
                foreach (var ultiParent in pair.Value)
                {
                    if (AlwaysIncludeAsset(ultiParent))
                    {
                        requiredParents++;
                    }
                }

                if (requiredParents <= 1)
                {
                    neverBundle.Add(pair.Key.ToLower());
                }
            }

            Debug.Log((neverBundle.Count - floor) + " asset have zero or one ultimate parents and won't be bundled");
            floor = neverBundle.Count;

            // Skip assets that are too small. This is a tradeoff between individual access to files,
            // versus the game not having an open file handle for every single 2 KB thing. We're choosing
            // to duplicate some things by baking them into multiple bundles, even though it requires
            // more storage and bandwidth.

            int tooSmallCount = 0;

            foreach (var asset in assetPaths)
            {
                if (neverBundle.Contains(asset.ToLower()))
                {
                    continue;
                }
                var diskPath = projectRoot + "/" + asset;
                var fileInfo = new System.IO.FileInfo(diskPath);
                if (fileInfo.Length < 10000)
                {
                    tooSmallCount++;
                    neverBundle.Add(asset.ToLower());
                }
            }

            Debug.Log(tooSmallCount + " assets are too small and won't be bundled");

            // Collect all assets to create as addressables

            string preamble         = "Assets/" + autoBundlesFolderName + "/";
            var    expresslyBundled = new HashSet <string>();

            foreach (var folder in folderNames)
            {
                var assetGuids = AssetDatabase.FindAssets(assetFilter, new [] { "Assets/" + autoBundlesFolderName + "/" + folder });

                // Schedule creation/moving of assets that exist

                foreach (var guid in assetGuids)
                {
                    var addrPath = AssetDatabase.GUIDToAssetPath(guid);

                    // Skip assets we're never bundling

                    string lowerPath = addrPath.ToLower();
                    if (neverBundle.Contains(lowerPath) && !AlwaysIncludeAsset(lowerPath))
                    {
                        continue;
                    }

                    // Remove the Assets/AutoBundles/ part of assets paths.

                    var shortPath = addrPath;

                    if (shortPath.StartsWith(preamble))
                    {
                        shortPath = shortPath.Substring(preamble.Length);
                    }

                    // Create asset creation/moving action.

                    string autoGroup = autoGroupPrefix + folder;

                    assetActions.Add(new AssetAction()
                    {
                        create          = true,
                        inGroup         = autoGroup,
                        assetGuid       = guid,
                        addressablePath = shortPath
                    });

                    AddressableAssetEntry entry = settings.FindAssetEntry(guid);
                    if (entry == null)
                    {
                        results.Add(new AnalyzeResult()
                        {
                            resultName = "Add:" + shortPath
                        });
                    }
                    else
                    {
                        results.Add(new AnalyzeResult()
                        {
                            resultName = "Keep or move:" + shortPath
                        });
                    }

                    expresslyBundled.Add(shortPath);
                }
            }

            // Schedule removal of assets in auto folders that exist as addressables but aren't expressly bundled.

            foreach (var folder in folderNames)
            {
                string autoName = autoGroupPrefix + folder;
                var    group    = settings.FindGroup(autoName);

                if (group != null)
                {
                    List <AddressableAssetEntry> result = new List <AddressableAssetEntry>();
                    group.GatherAllAssets(result, true, false, true);

                    foreach (var entry in result)
                    {
                        if (entry.IsSubAsset)
                        {
                            continue;
                        }
                        if (entry.guid == "")
                        {
                            Debug.Log("Entry has no guid! " + entry.address);
                        }

                        if (!expresslyBundled.Contains(entry.address))
                        {
                            assetActions.Add(new AssetAction()
                            {
                                create          = false,
                                inGroup         = autoName,
                                assetGuid       = entry.guid,
                                addressablePath = entry.address,
                            });

                            // Print removal message without preamble

                            results.Add(new AnalyzeResult()
                            {
                                resultName = "Remove:" + entry.address
                            });
                        }
                    }
                }
            }

            return(results);
        }
Ejemplo n.º 22
0
        public override void FixIssues(AddressableAssetSettings settings)
        {
            // Load template used for creating new groups

            var groupTemplates = settings.GroupTemplateObjects;
            AddressableAssetGroupTemplate foundTemplate = null;

            foreach (var template in groupTemplates)
            {
                if (template.name == templateToUse)
                {
                    foundTemplate = template as AddressableAssetGroupTemplate;
                    break;
                }
            }

            if (foundTemplate == null)
            {
                Debug.Log("Group template \"" + templateToUse + "\" not found. Aborting!");
                return;
            }

            // Create groups

            foreach (var groupName in groupsToCreate)
            {
                // I don't know enough about schemas, so schemasToCopy is set to null here.
                AddressableAssetGroup newGroup = settings.CreateGroup(groupName, false, false, true, null, foundTemplate.GetTypes());
                foundTemplate.ApplyToAddressableAssetGroup(newGroup);
            }

            // Remove groups

            foreach (var groupName in groupsToRemove)
            {
                foreach (var group in settings.groups)
                {
                    if (group.name == groupName)
                    {
                        settings.RemoveGroup(group);
                        break;
                    }
                }
            }

            // Collect current group names

            Dictionary <string, AddressableAssetGroup> groups = new Dictionary <string, AddressableAssetGroup>();

            foreach (var group in settings.groups)
            {
                groups.Add(group.name, group);
            }

            // Create and remove assets

            foreach (var action in assetActions)
            {
                if (!groups.ContainsKey(action.inGroup))
                {
                    continue;
                }

                if (action.create)
                {
                    AddressableAssetEntry entry = settings.CreateOrMoveEntry(action.assetGuid, groups[action.inGroup]);
                    entry.SetAddress(action.addressablePath);
                }
                else
                {
                    AddressableAssetEntry entry = settings.FindAssetEntry(action.assetGuid);
                    if (entry != null)
                    {
                        settings.RemoveAssetEntry(action.assetGuid);
                    }
                    else
                    {
                        Debug.Log("Asset guid didn't produce an entry: " + action.assetGuid);
                    }
                }
            }

            ClearAnalysis();
            ClearOurData();
        }
    void OnWizardCreate()
    {
        //save/update any editor prefs we have changed
        EditorPrefs.SetString("ARW_Prefix0", prefix0);
        EditorPrefs.SetString("ARW_Prefix1", prefix1);
        EditorPrefs.SetString("ARW_Prefix2", prefix2);
        EditorPrefs.SetString("ARW_Postfix0", postfix0);
        EditorPrefs.SetBool("ARW_Prepend", prependFolderName);

        string[] assetGUIDs = Selection.assetGUIDs;
        if (assetGUIDs != null)
        {
            AddressableAssetSettings settings = AddressableAssetSettingsDefaultObject.Settings;
            if (settings == null)
            {
                Debug.LogError("Could not find AddressableAssetSettings!");
                return;
            }

            var           entries    = new List <AddressableAssetEntry>();
            StringBuilder newAddress = new StringBuilder(50);

            foreach (string assetGUID in assetGUIDs)
            {
                AddressableAssetEntry entry = settings.FindAssetEntry(assetGUID);
                if (entry != null)
                {
                    string assetName  = Path.GetFileNameWithoutExtension(entry.AssetPath);
                    string folderName = Path.GetFileName(Path.GetDirectoryName(entry.AssetPath));
                    newAddress.Clear();

                    if (!string.IsNullOrEmpty(prefix0))
                    {
                        newAddress.Append(prefix0); newAddress.Append(".");
                    }
                    if (!string.IsNullOrEmpty(prefix1))
                    {
                        newAddress.Append(prefix1); newAddress.Append(".");
                    }
                    if (!string.IsNullOrEmpty(prefix2))
                    {
                        newAddress.Append(prefix2); newAddress.Append(".");
                    }
                    if (prependFolderName)
                    {
                        newAddress.Append(folderName); newAddress.Append(".");
                    }
                    newAddress.Append(assetName);
                    if (!string.IsNullOrEmpty(postfix0))
                    {
                        newAddress.Append("."); newAddress.Append(postfix0);
                    }

                    entry.SetAddress(newAddress.ToString(), false);

                    foreach (string label in labelsToAdd)
                    {
                        entry.SetLabel(label, true, false, false);
                    }

                    foreach (string label in labelsToRemove)
                    {
                        entry.SetLabel(label, false, false, false);
                    }

                    entries.Add(entry);
                }
                else
                {
                    string assetPath = AssetDatabase.GUIDToAssetPath(assetGUID);
                    if (string.IsNullOrEmpty(assetPath))
                    {
                        Debug.LogWarning(assetGUID + " is not marked as Addressable.");
                    }
                    else
                    {
                        Debug.LogWarning(assetPath + " is not marked as Addressable.");
                    }
                }
            }

            settings.SetDirty(AddressableAssetSettings.ModificationEvent.EntryModified, entries, true, false);
        }
    }
        static void SetAaEntry(AddressableAssetSettings aaSettings, List <TargetInfo> targetInfos, bool create)
        {
            /*
             * if (create && aaSettings.DefaultGroup.ReadOnly)
             * {
             *  Debug.LogError("Current default group is ReadOnly.  Cannot add addressable assets to it");
             *  return;
             * }
             */

            Undo.RecordObject(aaSettings, "AddressableAssetSettings");

            if (!create)
            {
                List <AddressableAssetEntry> removedEntries = new List <AddressableAssetEntry>(targetInfos.Count);
                for (int i = 0; i < targetInfos.Count; ++i)
                {
                    AddressableAssetEntry e = aaSettings.FindAssetEntry(targetInfos[i].Guid);
                    AddressableAssetUtility.OpenAssetIfUsingVCIntegration(e.parentGroup);
                    removedEntries.Add(e);
                    aaSettings.RemoveAssetEntry(removedEntries[i], false);
                }
                if (removedEntries.Count > 0)
                {
                    aaSettings.SetDirty(AddressableAssetSettings.ModificationEvent.EntryRemoved, removedEntries, true, false);
                }
            }
            else
            {
                AddressableAssetGroup parentGroup = aaSettings.DefaultGroup;
                var resourceTargets = targetInfos.Where(ti => AddressableAssetUtility.IsInResources(ti.Path));
                if (resourceTargets.Any())
                {
                    var resourcePaths = resourceTargets.Select(t => t.Path).ToList();
                    var resourceGuids = resourceTargets.Select(t => t.Guid).ToList();
                    AddressableAssetUtility.SafeMoveResourcesToGroup(aaSettings, parentGroup, resourcePaths, resourceGuids);
                }

                var entriesCreated   = new List <AddressableAssetEntry>();
                var entriesMoved     = new List <AddressableAssetEntry>();
                var otherTargetInfos = targetInfos.Except(resourceTargets);
                foreach (var info in otherTargetInfos)
                {
                    var hook = aaSettings.hook;
                    AddressableAssetGroup assetGroup = default;
                    string customAddress             = default;
                    if (hook != null)
                    {
                        hook.BeforeSetEntryOnInspectorGUI(info.Path, out assetGroup, out customAddress);
                    }
                    if (assetGroup == null)
                    {
                        assetGroup = aaSettings.DefaultGroup;
                    }

                    string guid = info.Guid;
                    if (string.IsNullOrEmpty(guid))
                    {
                        continue;
                    }

                    AddressableAssetEntry e = aaSettings.FindAssetEntry(guid);
                    if (e != null) //move entry to where it should go...
                    {
                        aaSettings.MoveEntry(e, assetGroup, false, false);
                    }
                    else //create entry
                    {
                        e = aaSettings.CreateAndAddEntryToGroup_Custom(guid, assetGroup, false, false);
                    }

                    if (string.IsNullOrEmpty(customAddress) == false)
                    {
                        e.SetAddress(customAddress, false);
                    }
                    entriesCreated.Add(e);
                    entriesMoved.Add(e);
                }

                bool openedInVC = false;
                if (entriesMoved.Count > 0)
                {
                    AddressableAssetUtility.OpenAssetIfUsingVCIntegration(parentGroup);
                    openedInVC = true;
                    aaSettings.SetDirty(AddressableAssetSettings.ModificationEvent.EntryMoved, entriesMoved, true, false);
                }

                if (entriesCreated.Count > 0)
                {
                    if (!openedInVC)
                    {
                        AddressableAssetUtility.OpenAssetIfUsingVCIntegration(parentGroup);
                    }
                    aaSettings.SetDirty(AddressableAssetSettings.ModificationEvent.EntryAdded, entriesCreated, true, false);
                }
            }
        }
Ejemplo n.º 25
0
        public override List <AnalyzeResult> RefreshAnalysis(AddressableAssetSettings settings)
        {
            List <AnalyzeResult> results = new List <AnalyzeResult>();

            ClearAnalysis();
            ClearOurData();

            if (!BuildUtility.CheckModifiedScenesAndAskToSave())
            {
                Debug.LogError("Cannot run Analyze with unsaved scenes");
                results.Add(new AnalyzeResult {
                    resultName = ruleName + "Cannot run Analyze with unsaved scenes"
                });
                return(results);
            }

            // Get all folders in Assets/AutoBundles

            HashSet <string> folderNames = new HashSet <string>();
            var folders = AssetDatabase.GetSubFolders("Assets/" + autoBundlesFolderName);

            foreach (var folder in folders)
            {
                folderNames.Add(Path.GetFileName(folder));
            }

            // Get all addressable groups carrying the (Auto) prefix

            HashSet <string> autoGroups = new HashSet <string>();

            foreach (var group in settings.groups)
            {
                if (group.name.StartsWith(autoGroupPrefix))
                {
                    autoGroups.Add(group.name);
                }
            }

            // Collect all groups that must be created or moved

            foreach (var folder in folderNames)
            {
                var autoName = autoGroupPrefix + folder;
                if (!autoGroups.Contains(autoName))
                {
                    groupsToCreate.Add(autoName);
                    results.Add(new AnalyzeResult()
                    {
                        resultName = "Create group \"" + autoName + "\""
                    });
                }
            }

            // Collect all groups that must be removed

            foreach (var groupName in autoGroups)
            {
                var baseName = groupName.Substring(autoGroupPrefix.Length);
                if (!folderNames.Contains(baseName))
                {
                    groupsToRemove.Add(groupName);
                    results.Add(new AnalyzeResult()
                    {
                        resultName = "Remove group \"" + groupName + "\""
                    });
                }
            }

            // Collect all assets that have zero or one references. They will not be bundled, because
            // Addressables will automatically bring them in. This reduces the number of individual bundles.

            Dictionary <string, int> refCounts = new Dictionary <string, int>();
            var guids = AssetDatabase.FindAssets(assetFilter, new [] { "Assets" });

            foreach (var guid in guids)
            {
                string path = AssetDatabase.GUIDToAssetPath(guid);

                var dependencies = AssetDatabase.GetDependencies(path);
                foreach (var asset in dependencies)
                {
                    if (asset == path)
                    {
                        // Ignore self
                        continue;
                    }
                    if (refCounts.ContainsKey(asset))
                    {
                        refCounts[asset]++;
                    }
                    else
                    {
                        refCounts[asset] = 1;
                    }
                }
            }

            // Select which items to never bundle. This includes items that have no references or only one references,
            // as well as unwanted file extensions.

            HashSet <string> neverBundle = new HashSet <string>();

            foreach (KeyValuePair <string, int> asset in refCounts)
            {
                if (asset.Value == 0 && neverBundleNoReferences || asset.Value == 1)
                {
                    neverBundle.Add(asset.Key);
                    break;
                }

                bool ignore = false;
                foreach (var ext in ignoreExtensions)
                {
                    if (asset.Key.ToLower().EndsWith(ext))
                    {
                        ignore = true;
                        break;
                    }
                }
                if (ignore)
                {
                    neverBundle.Add(asset.Key);
                }
            }

            // Collect all assets to create as addressables

            string preamble = "Assets/" + autoBundlesFolderName + "/";

            foreach (var folder in folderNames)
            {
                var assetGuids = AssetDatabase.FindAssets(assetFilter, new [] { "Assets/" + autoBundlesFolderName + "/" + folder });

                // Schedule creation/moving of assets that exist

                foreach (var guid in assetGuids)
                {
                    var addrPath = AssetDatabase.GUIDToAssetPath(guid);

                    // Skip assets we're never bundling

                    if (neverBundle.Contains(addrPath))
                    {
                        continue;
                    }

                    // Remove the Assets/AutoBundles/ part of assets paths.

                    if (addrPath.StartsWith(preamble))
                    {
                        addrPath = addrPath.Substring(preamble.Length);
                    }

                    // Create asset creation/moving action.

                    string autoGroup = autoGroupPrefix + folder;

                    assetActions.Add(new AssetAction()
                    {
                        create          = true,
                        inGroup         = autoGroup,
                        assetGuid       = guid,
                        addressablePath = addrPath
                    });

                    AddressableAssetEntry entry = settings.FindAssetEntry(guid);
                    if (entry == null)
                    {
                        results.Add(new AnalyzeResult()
                        {
                            resultName = "Add:" + addrPath
                        });
                    }
                    else
                    {
                        results.Add(new AnalyzeResult()
                        {
                            resultName = "Keep or move:" + addrPath
                        });
                    }
                }

                // Schedule removal of assets that exist as addressables but don't exist anywhere under the AutoBundles tree

                string autoName = autoGroupPrefix + folder;
                var    group    = settings.FindGroup(autoName);

                if (group != null)
                {
                    List <AddressableAssetEntry> result = new List <AddressableAssetEntry>();
                    group.GatherAllAssets(result, true, true, true);

                    foreach (var entry in result)
                    {
                        if (entry.IsSubAsset)
                        {
                            continue;
                        }
                        if (entry.guid == "")
                        {
                            Debug.Log("Entry has no guid! " + entry.address);
                        }

                        string assetPath = AssetDatabase.GUIDToAssetPath(entry.guid);


                        if (!assetPath.StartsWith("Assets/" + autoBundlesFolderName + "/"))
                        {
                            assetActions.Add(new AssetAction()
                            {
                                create          = false,
                                inGroup         = autoName,
                                assetGuid       = entry.guid,
                                addressablePath = entry.address,
                            });

                            // Print removal message without preamble

                            results.Add(new AnalyzeResult()
                            {
                                resultName = "Remove:" + entry.address
                            });
                        }
                    }
                }
            }

            return(results);
        }