favoyang / unity-addressable-importer

A rule based addressable asset importer
MIT License
885 stars 124 forks source link

About asset dependencies. #14

Closed DumoeDss closed 4 years ago

DumoeDss commented 4 years ago

Some dependencies assets is not in the same folder with target asset, so the pack rules will not pack the dependencies assets. I try to add assets' dependencies at OnPostprocessAllAssets, and make the asset's dependencies' group name same to the asset at CreateOrUpdateAddressableAssetEntry. It works meet my expectations. I want to know that is there has any question if I do this change.

static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
    {
        var settings = AddressableAssetSettingsDefaultObject.Settings;
        var importSettings = AddressableImportSettings.Instance;
        if (importSettings == null || importSettings.rules == null || importSettings.rules.Count == 0)
            return;
        var entriesAdded = new List<AddressableAssetEntry>();
        foreach (string assetPath in importedAssets)
        {
            foreach (var rule in importSettings.rules)
            {
                if (rule.Match(assetPath))
                {
                    var entry = CreateOrUpdateAddressableAssetEntry(settings, importSettings, rule, assetPath);
                    if (entry != null)
                    {
                        entriesAdded.Add(entry);
                        if (rule.HasLabel)
                            Debug.LogFormat("[AddressableImporter] Entry created/updated for {0} with address {1} and labels {2}", assetPath, entry.address, string.Join(", ", entry.labels));
                        else
                            Debug.LogFormat("[AddressableImporter] Entry created/updated for {0} with address {1}", assetPath, entry.address);
                    }

                    string[] dependencies = AssetDatabase.GetDependencies(new string[] { assetPath });
                    foreach (var dependency in dependencies)
                    {
                        string path = dependency.Replace('\\', '/');
                        entry = CreateOrUpdateAddressableAssetEntry(settings, importSettings, rule, path, assetPath);
                        if (entry != null)
                        {
                            entriesAdded.Add(entry);
                            if (rule.HasLabel)
                                Debug.LogFormat("[AddressableImporter] Entry created/updated for {0} with address {1} and labels {2}", assetPath, entry.address, string.Join(", ", entry.labels));
                            else
                                Debug.LogFormat("[AddressableImporter] Entry created/updated for {0} with address {1}", assetPath, entry.address);
                        }

                    }
                }
            }
        }
        if (entriesAdded.Count > 0)
        {
            settings.SetDirty(AddressableAssetSettings.ModificationEvent.EntryMoved, entriesAdded, true);
            AssetDatabase.SaveAssets();
        }
        if (importSettings.removeEmtpyGroups)
        {
            settings.groups.RemoveAll(_ => _.entries.Count == 0 && !_.IsDefaultGroup());
        }
    }

    static AddressableAssetEntry CreateOrUpdateAddressableAssetEntry(
       AddressableAssetSettings settings,
       AddressableImportSettings importSettings,
       AddressableImportRule rule,
       string assetPath, string dependency = "")
    {
        // Set group
        AddressableAssetGroup group;
        string groupName;
        if (string.IsNullOrEmpty(dependency))
        {
            groupName = rule.ParseGroupReplacement(assetPath);
        }
        else
        {
            groupName = rule.ParseGroupReplacement(dependency);
        }
        bool newGroup = false;
        if (!TryGetGroup(settings, groupName, out group))
        {
            if (importSettings.allowGroupCreation)
            {
                //TODO Specify on editor which type to create.
                group = CreateAssetGroup<BundledAssetGroupSchema>(settings, groupName);
                newGroup = true;
            }
            else
            {
                Debug.LogErrorFormat("[AddressableImporter] Failed to find group {0} when importing {1}. Please check if the group exists, then reimport the asset.", rule.groupName, assetPath);
                return null;
            }
        }

        // Set group settings from template if necessary
        if (rule.groupTemplate != null && (newGroup || rule.groupTemplateApplicationMode == GroupTemplateApplicationMode.AlwaysOverwriteGroupSettings))
        {
            rule.groupTemplate.ApplyToAddressableAssetGroup(group);
        }

        var guid = AssetDatabase.AssetPathToGUID(assetPath);
        var entry = settings.CreateOrMoveEntry(guid, group);

        // Apply address replacement if address is empty or path.
        if (string.IsNullOrEmpty(entry.address) ||
            entry.address.StartsWith("Assets/") ||
            rule.simplified ||
            !string.IsNullOrWhiteSpace(rule.addressReplacement))
        {
            entry.address = rule.ParseAddressReplacement(assetPath);
        }

        // Add labels
        if (rule.LabelMode == LabelWriteMode.Replace)
            entry.labels.Clear();
        foreach (var label in rule.labels)
        {
            entry.labels.Add(label);
        }
        return entry;
    }
favoyang commented 4 years ago

Hi @DumoeDss,

Thanks for report the issue. It seems you want to find all dependencies and add them to the depended group. However I doubt if the it is necessary. Since during the build process, all dependencies will be collected and handled correctly by addressable system. i.e. using the importer or not, you can drag a prefab (with reference to other assets) to addressable group, and all the dependencies will be added to the group. You can use assert bundle browser tool to verify these once you located the local / remote build folder.

Let me know if I understand you correctly.

DumoeDss commented 4 years ago

Hi @favoyang , Thanks for your interpretation. I'm just migrated from asset bundle to addressable, so I'm not too familiar with addressable. I thought I needed to add denpendencies manually such as the asset bundle due to I'm find that the dependenices assets not appear at the asset list, and I'm not sure if I did it right, so I opend this issue. I understand it now, Thanks again for your interpretation.

favoyang commented 4 years ago

Glad it helps. I'll close this for now and feel free to re-open it if you find anything surprising you about the dependency handling.