string ProcessVariants(ProcessVariantAssetsSchema schema, AddressableAssetGroup group, AddressableAssetsBuildContext context)
        {
            var settings = context.Settings;

            var entries = new List <AddressableAssetEntry>(group.entries);

            foreach (var mainEntry in entries)
            {
                if (AssetDatabase.GetMainAssetTypeAtPath(mainEntry.AssetPath) != typeof(GameObject))
                {
                    continue;
                }

                GameObject mainAsset = AssetDatabase.LoadMainAssetAtPath(mainEntry.AssetPath) as GameObject;
                if (!schema.PreprocessCheck(mainAsset))
                {
                    continue;
                }

                string fileName      = Path.GetFileNameWithoutExtension(mainEntry.AssetPath);
                string mainAssetPath = AssetDatabase.GUIDToAssetPath(mainEntry.guid);

                string groupDirectory = Path.Combine(defaultBaseDirectory, $"{group.Name}").Replace('\\', '/');
                string newPrefabPath  = groupDirectory + '/' + Path.GetFileName(mainEntry.AssetPath).Replace(fileName, $"{fileName}_variant");
                Directory.CreateDirectory(groupDirectory);

                if (!AssetDatabase.CopyAsset(mainAssetPath, newPrefabPath))
                {
                    Debug.LogError("Failed to copy asset " + mainAssetPath);
                    continue;
                }
                if (schema.deleteVariants)
                {
                    variantsPrefabsToDelete.Add(newPrefabPath);
                }
                GameObject variant = AssetDatabase.LoadAssetAtPath <GameObject>(newPrefabPath);

                foreach (var script in schema.variantAssetsScripts)
                {
                    script.ProcessVariantAsset(variant);
                }

                //Create the Variant Entry and set it's address and labels.
                var variantEntry = settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(newPrefabPath), mainEntry.parentGroup, false, false);
                variantEntry.address = mainEntry.address;
                foreach (string label in mainEntry.labels)
                {
                    variantEntry.SetLabel(label, true, false, false);
                }
                variantEntriesToRemove.Add(AssetDatabase.AssetPathToGUID(newPrefabPath));
                entriesToRestore.Add(new AssetEntry {
                    address = mainEntry.address, assetGUID = mainEntry.guid, group = mainEntry.parentGroup, labels = mainEntry.labels
                });
                settings.RemoveAssetEntry(AssetDatabase.AssetPathToGUID(mainEntry.AssetPath), false);
            }

            return(string.Empty);
        }
        protected override string ProcessGroup(AddressableAssetGroup assetGroup, AddressableAssetsBuildContext aaContext)
        {
            if (assetGroup.HasSchema <ProcessVariantAssetsSchema>())
            {
                ProcessVariantAssetsSchema schema = assetGroup.GetSchema <ProcessVariantAssetsSchema>();
                var errorString = ProcessVariants(schema, assetGroup, aaContext);
                if (!string.IsNullOrEmpty(errorString))
                {
                    return(errorString);
                }
            }

            return(base.ProcessGroup(assetGroup, aaContext));
        }