public void BundledAssetGroupSchema_SetPathVariable_ProperlySetsReferenceOnPath() { AddressableAssetGroup group = null; ProfileValueReference pathValue = null; BundledAssetGroupSchema schema = null; try { Type[] types = new Type[] {}; group = m_Settings.CreateGroup("Group1", false, false, false, null, types); List <string> variableNames = new List <string>(); variableNames.Add("LocalBuildPath"); variableNames.Add(AddressableAssetSettings.kLocalBuildPath); schema = ScriptableObject.CreateInstance <BundledAssetGroupSchema>(); schema.SetPathVariable(group.Settings, ref pathValue, AddressableAssetSettings.kLocalBuildPath, "LocalBuildPath", variableNames); } finally { if (group != null) { m_Settings.RemoveGroupInternal(group, true, false); } if (schema != null) { ScriptableObject.DestroyImmediate(schema); } } }
internal static string ErrorCheckBundleSettings(BundledAssetGroupSchema schema, AddressableAssetGroup assetGroup, AddressableAssetSettings settings) { var message = string.Empty; var buildPath = settings.profileSettings.GetValueById(settings.activeProfileId, schema.BuildPath.Id); var loadPath = settings.profileSettings.GetValueById(settings.activeProfileId, schema.LoadPath.Id); var buildLocal = buildPath.Contains("[UnityEngine.AddressableAssets.Addressables.BuildPath]"); var loadLocal = loadPath.Contains("{UnityEngine.AddressableAssets.Addressables.RuntimePath}"); if (buildLocal && !loadLocal) { message = "BuildPath for group '" + assetGroup.Name + "' is set to the dynamic-lookup version of StreamingAssets, but LoadPath is not. \n"; } else if (!buildLocal && loadLocal) { message = "LoadPath for group " + assetGroup.Name + " is set to the dynamic-lookup version of StreamingAssets, but BuildPath is not. These paths must both use the dynamic-lookup, or both not use it. \n"; } if (!string.IsNullOrEmpty(message)) { message += "BuildPath: '" + buildPath + "'\n"; message += "LoadPath: '" + loadPath + "'"; } return(message); }
private static void SetGroupsSetting(AddressableAssetGroup group, bool UseAssetBundleCache, bool UseAssetBundleCrc, BundledAssetGroupSchema.BundleNamingStyle BundleNaming, string BuildPath, string LoadPath, bool StaticContent) { BundledAssetGroupSchema bundledAssetGroupSchema = group.GetSchema <BundledAssetGroupSchema>(); if (bundledAssetGroupSchema == null) { bundledAssetGroupSchema = group.AddSchema <BundledAssetGroupSchema>(); } //bundledAssetGroupSchema.IncludeInBuild = true; bundledAssetGroupSchema.UseAssetBundleCache = UseAssetBundleCache; bundledAssetGroupSchema.UseAssetBundleCrc = UseAssetBundleCrc; bundledAssetGroupSchema.BundleNaming = BundleNaming; bundledAssetGroupSchema.BuildPath.SetVariableByName(group.Settings, BuildPath); bundledAssetGroupSchema.LoadPath.SetVariableByName(group.Settings, LoadPath); bundledAssetGroupSchema.SetAssetBundleProviderType(typeof(AssetBundleEncryptProvider)); EditorUtility.SetDirty(bundledAssetGroupSchema); ContentUpdateGroupSchema contentUpdateGroupSchema = group.GetSchema <ContentUpdateGroupSchema>(); if (contentUpdateGroupSchema == null) { contentUpdateGroupSchema = group.AddSchema <ContentUpdateGroupSchema>(); } contentUpdateGroupSchema.StaticContent = StaticContent; EditorUtility.SetDirty(contentUpdateGroupSchema); }
private static AddressableAssetGroup CreateGroup(string groupName) { //アドレサブルアセットセッティング取得 AddressableAssetSettings assetSettings = GetSettings(); BundledAssetGroupSchema assetGroupSchema = CreateInstance <BundledAssetGroupSchema>(); if (groupName.IndexOf(REMOTE_GROUP, StringComparison.OrdinalIgnoreCase) >= 0) { assetGroupSchema.BuildPath.SetVariableByName(assetSettings, AddressableAssetSettings.kRemoteBuildPath); assetGroupSchema.LoadPath.SetVariableByName(assetSettings, AddressableAssetSettings.kRemoteLoadPath); } //スキーマ生成 List <AddressableAssetGroupSchema> schema = new List <AddressableAssetGroupSchema>() { CreateInstance <ContentUpdateGroupSchema>(), assetGroupSchema, }; //グループの作成 AddressableAssetGroup assetGroup = assetSettings.groups.Find((g) => g.name == groupName); return(assetGroup == null ? assetSettings.CreateGroup(groupName, false, false, true, schema) : assetGroup); }
static void SaveProfile() { ModBuilderProfile currentProfile = profiles[profileIndex]; ModBuilderProfile mbp = new ModBuilderProfile(); mbp.groups = new Dictionary <string, bool>(); foreach (AddressableAssetGroup group in AddressableAssetSettingsDefaultObject.Settings.groups) { BundledAssetGroupSchema bundledAssetGroupSchema = group.GetSchema <BundledAssetGroupSchema>(); if (bundledAssetGroupSchema != null) { mbp.groups.Add(group.Name, group.GetSchema <BundledAssetGroupSchema>().IncludeInBuild); } } mbp.profileName = currentProfile.profileName; mbp.exportFolder = exportFolderName; profiles[profileIndex] = mbp; string json = JsonConvert.SerializeObject(profiles, Formatting.Indented); using (StreamWriter sw = new StreamWriter(Application.dataPath + "/SDK/modprofiles.json")) { sw.Write(json); sw.Close(); } }
static void OnProfileIndexChange() { ModBuilderProfile currentProfile = profiles[profileIndex]; foreach (AddressableAssetGroup group in AddressableAssetSettingsDefaultObject.Settings.groups) { BundledAssetGroupSchema bundledAssetGroupSchema = group.GetSchema <BundledAssetGroupSchema>(); if (bundledAssetGroupSchema != null) { if (currentProfile.groups != null) { if (currentProfile.groups.ContainsKey(group.Name)) { group.GetSchema <BundledAssetGroupSchema>().IncludeInBuild = currentProfile.groups[group.Name]; } else { Debug.LogWarning("Group " + group.Name + " not found in profile " + currentProfile.profileName + "."); } } else { CheckAll(false); } } } exportFolderName = currentProfile.exportFolder; }
private static void UpdateGroupBuildAndLoadPath(AddressableAssetSettings settings, string path) { List <AddressableAssetGroupSchema> schemas = AssetDatabase.LoadAssetAtPath <AddressableAssetGroup>(path).Schemas; BundledAssetGroupSchema bundledAssetGroupSchema = schemas.Find(p => p.GetType() == typeof(BundledAssetGroupSchema)) as BundledAssetGroupSchema; if (bundledAssetGroupSchema != null) { bundledAssetGroupSchema.BuildPath.SetVariableByName(settings, AddressableAssetSettings.kRemoteBuildPath); bundledAssetGroupSchema.LoadPath.SetVariableByName(settings, AddressableAssetSettings.kRemoteLoadPath); } }
private static void CheckAll(bool b) { foreach (AddressableAssetGroup group in AddressableAssetSettingsDefaultObject.Settings.groups) { BundledAssetGroupSchema bundledAssetGroupSchema = group.GetSchema <BundledAssetGroupSchema>(); if (bundledAssetGroupSchema != null) { group.GetSchema <BundledAssetGroupSchema>().IncludeInBuild = b; } } }
AddressableAssetGroup CreateGroup(string groupName) { string guid = AssetDatabase.FindAssets("t:AddressableAssetSettings").FirstOrDefault(); string path = AssetDatabase.GUIDToAssetPath(guid); AddressableAssetSettings settings = AssetDatabase.LoadAssetAtPath <AddressableAssetSettings>(path); BundledAssetGroupSchema bundledAssetGroupSchema = ScriptableObject.CreateInstance <BundledAssetGroupSchema>(); ContentUpdateGroupSchema contentUpdateGroupSchema = ScriptableObject.CreateInstance <ContentUpdateGroupSchema>(); var schemas = new List <AddressableAssetGroupSchema> { bundledAssetGroupSchema, contentUpdateGroupSchema }; return(settings.CreateGroup(groupName, false, false, true, schemas)); }
private static void SetAllGroupsToAssetBundleEncryptProvider() { AddressableAssetSettings settings = AASUtility.GetSettings(); foreach (var group in settings.groups) { BundledAssetGroupSchema bundledAssetGroupSchema = group.GetSchema <BundledAssetGroupSchema>(); if (bundledAssetGroupSchema == null) { bundledAssetGroupSchema = group.AddSchema <BundledAssetGroupSchema>(); } bundledAssetGroupSchema.SetAssetBundleProviderType(typeof(AssetBundleEncryptProvider)); EditorUtility.SetDirty(bundledAssetGroupSchema); } AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); }
/// <summary> /// The processing of the bundled asset schema. This is where the bundle(s) for a given group are actually setup. /// </summary> /// <param name="schema">The BundledAssetGroupSchema to process</param> /// <param name="assetGroup">The group this schema was pulled from</param> /// <param name="aaContext">The general Addressables build builderInput</param> /// <returns>The error string, if any.</returns> protected virtual string ProcessBundledAssetSchema( BundledAssetGroupSchema schema, AddressableAssetGroup assetGroup, AddressableAssetsBuildContext aaContext) { if (schema == null || !schema.IncludeInBuild || !assetGroup.entries.Any()) { return(string.Empty); } var errorStr = ErrorCheckBundleSettings(schema, assetGroup, aaContext.settings); if (!string.IsNullOrEmpty(errorStr)) { return(errorStr); } var bundledProviderId = schema.GetBundleCachedProviderId(); var assetProviderId = schema.GetAssetCachedProviderId(); if (!m_CreatedProviderIds.Contains(bundledProviderId)) { m_CreatedProviderIds.Add(bundledProviderId); var bundleProviderType = schema.AssetBundleProviderType.Value; var bundleProviderData = ObjectInitializationData.CreateSerializedInitializationData(bundleProviderType, bundledProviderId); m_ResourceProviderData.Add(bundleProviderData); } if (!m_CreatedProviderIds.Contains(assetProviderId)) { m_CreatedProviderIds.Add(assetProviderId); var assetProviderType = schema.BundledAssetProviderType.Value; var assetProviderData = ObjectInitializationData.CreateSerializedInitializationData(assetProviderType, assetProviderId); m_ResourceProviderData.Add(assetProviderData); } var bundleInputDefs = new List <AssetBundleBuild>(); PrepGroupBundlePacking(assetGroup, bundleInputDefs, schema.BundleMode); HandleDuplicateBundleNames(bundleInputDefs, aaContext.bundleToAssetGroup, assetGroup.Guid, out var uniqueNames); m_OutputAssetBundleNames.AddRange(uniqueNames); m_AllBundleInputDefs.AddRange(bundleInputDefs); return(string.Empty); }
//创建组 private static AddressableAssetGroup CreateOrGetNonStaticGroup(AddressableAssetSettings settings, string groupName) { var group = settings.FindGroup(groupName); if (group == null) { group = settings.CreateGroup(groupName, false, false, false, null, typeof(BundledAssetGroupSchema), typeof(ContentUpdateGroupSchema)); } group.GetSchema <ContentUpdateGroupSchema>().StaticContent = false; BundledAssetGroupSchema groupSchema = group.GetSchema <BundledAssetGroupSchema>(); //groupSchema.UseAssetBundleCrc = false; //groupSchema.BundleNaming = BundledAssetGroupSchema.BundleNamingStyle.OnlyHash; groupSchema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackSeparately; groupSchema.BuildPath.SetVariableByName(settings, AddressableAssetSettings.kRemoteBuildPath); groupSchema.BuildPath.SetVariableByName(settings, AddressableAssetSettings.kRemoteLoadPath); return(group); }
/// <summary> /// グループを作成する /// </summary> private static AddressableAssetGroup GetOrCreateGroup(string groupName) { var settings = Settings; // すでにあれば何もしない var group = settings.groups.Find(group => group.name == groupName); if (group != null) { return(group); } var schema = new List <AddressableAssetGroupSchema>() { BundledAssetGroupSchema.CreateInstance <BundledAssetGroupSchema>(), ContentUpdateGroupSchema.CreateInstance <ContentUpdateGroupSchema>() }; return(settings.CreateGroup(groupName, setAsDefaultGroup: false, readOnly: false, postEvent: true, schema)); }
public void WhenBundleContainsMultipleFiles_FilesAndSizesMatchArchiveContent() { AddressableAssetGroup groupScenes = CreateGroup("SceneGroup"); AddressableAssetGroup textureGroup = CreateGroup("TextureGroup"); string scenePath = $"{TempPath}/scene.unity"; Scene scene1 = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene); new GameObject().AddComponent <TestBehaviourWithReference>(); EditorSceneManager.SaveScene(scene1, scenePath); AddressableAssetEntry e = m_Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(scenePath), groupScenes); EditorSceneManager.NewScene(NewSceneSetup.EmptyScene); CreateAddressableTexture("t1", textureGroup, 256); BuildLayout layout = BuildAndExtractLayout(); BundledAssetGroupSchema schema = m_Settings.groups.First(x => x.HasSchema <BundledAssetGroupSchema>()).GetSchema <BundledAssetGroupSchema>(); string path = schema.BuildPath.GetValue(m_Settings); foreach (BuildLayout.Bundle bundle in layout.Groups.SelectMany(x => x.Bundles)) { AssertEditorBundleDetailsMatchPhysicalBundle(Path.Combine(path, bundle.Name), bundle); } }
private AddressableAssetGroup GetGroup(AddressableAssetSettings settings, string groupName) { for (int i = 0; i < settings.groups.Count; ++i) { if (settings.groups[i].Name == groupName) { return(settings.groups[i]); } } List <AddressableAssetGroupSchema> schemas = new List <AddressableAssetGroupSchema>(); ContentUpdateGroupSchema contentUpdateGroupSchema = ScriptableObject.CreateInstance <ContentUpdateGroupSchema>(); BundledAssetGroupSchema bundledAssetGroupSchema = ScriptableObject.CreateInstance <BundledAssetGroupSchema>(); bundledAssetGroupSchema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackSeparately; schemas.Add(contentUpdateGroupSchema); schemas.Add(bundledAssetGroupSchema); AddressableAssetGroup group = settings.CreateGroup(groupName, false, false, false, schemas); return(group); }
/// <summary> /// The processing of the bundled asset schema. This is where the bundle(s) for a given group are actually setup. /// </summary> /// <param name="schema">The BundledAssetGroupSchema to process</param> /// <param name="assetGroup">The group this schema was pulled from</param> /// <param name="aaContext">The general Addressables build builderInput</param> /// <returns>The error string, if any.</returns> protected virtual string ProcessBundledAssetSchema( BundledAssetGroupSchema schema, AddressableAssetGroup assetGroup, AddressableAssetsBuildContext aaContext) { if (schema == null || !schema.IncludeInBuild) { return(string.Empty); } var errorStr = ErrorCheckBundleSettings(schema, assetGroup, aaContext.settings); if (!string.IsNullOrEmpty(errorStr)) { return(errorStr); } var bundledProviderId = schema.GetBundleCachedProviderId(); var assetProviderId = schema.GetAssetCachedProviderId(); if (!m_CreatedProviderIds.Contains(bundledProviderId)) { m_CreatedProviderIds.Add(bundledProviderId); var bundleProviderType = schema.AssetBundleProviderType.Value; var bundleProviderData = ObjectInitializationData.CreateSerializedInitializationData(bundleProviderType, bundledProviderId); m_ResourceProviderData.Add(bundleProviderData); } if (!m_CreatedProviderIds.Contains(assetProviderId)) { m_CreatedProviderIds.Add(assetProviderId); var assetProviderType = schema.BundledAssetProviderType.Value; var assetProviderData = ObjectInitializationData.CreateSerializedInitializationData(assetProviderType, assetProviderId); m_ResourceProviderData.Add(assetProviderData); } var bundleInputDefs = new List <AssetBundleBuild>(); PrepGroupBundlePacking(assetGroup, bundleInputDefs, schema.BundleMode); for (int i = 0; i < bundleInputDefs.Count; i++) { if (aaContext.bundleToAssetGroup.ContainsKey(bundleInputDefs[i].assetBundleName)) { var bid = bundleInputDefs[i]; int count = 1; var newName = bid.assetBundleName; while (aaContext.bundleToAssetGroup.ContainsKey(newName) && count < 1000) { newName = bid.assetBundleName.Replace(".bundle", string.Format("{0}.bundle", count++)); } bundleInputDefs[i] = new AssetBundleBuild { assetBundleName = newName, addressableNames = bid.addressableNames, assetBundleVariant = bid.assetBundleVariant, assetNames = bid.assetNames }; } aaContext.bundleToAssetGroup.Add(bundleInputDefs[i].assetBundleName, assetGroup.Guid); } m_AllBundleInputDefs.AddRange(bundleInputDefs); return(string.Empty); }
protected virtual string ConstructAssetBundleName(AddressableAssetGroup assetGroup, BundledAssetGroupSchema schema, BundleDetails info, string assetBundleName) { string groupName = assetGroup.Name.Replace(" ", "").Replace('\\', '/').Replace("//", "/").ToLower(); assetBundleName = groupName + "_" + assetBundleName; return(BuildUtility.GetNameWithHashNaming(schema.BundleNaming, info.Hash.ToString(), assetBundleName)); }
static void Build(Action behaviour) { // Check error if (exportTo == ExportTo.Project && !Directory.Exists(Path.Combine(projectPath, "Assets/StreamingAssets"))) { Debug.LogError("Cannot deploy to project dir as the folder doesn't seem to be an Unity project"); return; } if (exportTo == ExportTo.Game) { bool gameSupported = false; foreach (string supportedGame in Enum.GetNames(typeof(SupportedGame))) { if (File.Exists(Path.Combine(gamePath, supportedGame + ".exe"))) { gameSupported = true; gameName = (SupportedGame)Enum.Parse(typeof(SupportedGame), supportedGame); } } if (!gameSupported) { Debug.LogError("Target game not supported!"); return; } } #if PrivateSDK if (exportTo == ExportTo.Android) { string adbPath = Path.Combine(EditorPrefs.GetString("AndroidSdkRoot"), "platform-tools", "adb.exe"); if (!EditorPrefs.HasKey("AndroidSdkRoot") || !File.Exists(adbPath)) { Debug.LogError("Android SDK is not installed!"); Debug.LogError("Path not found " + adbPath); return; } } #endif // Configure stereo rendering if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android) { PlayerSettings.stereoRenderingPath = StereoRenderingPath.SinglePass; } if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneWindows || EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneWindows64) { PlayerSettings.stereoRenderingPath = StereoRenderingPath.Instancing; } // Configure addressable groups if (AddressableAssetSettingsDefaultObject.Settings != null) { foreach (AddressableAssetGroup group in AddressableAssetSettingsDefaultObject.Settings.groups) { BundledAssetGroupSchema bundledAssetGroupSchema = group.GetSchema <BundledAssetGroupSchema>(); if (bundledAssetGroupSchema != null) { if (group.Default) { bundledAssetGroupSchema.BuildPath.SetVariableByName(AddressableAssetSettingsDefaultObject.Settings, "LocalBuildPath"); bundledAssetGroupSchema.LoadPath.SetVariableByName(AddressableAssetSettingsDefaultObject.Settings, "LocalLoadPath"); } bundledAssetGroupSchema.BundleNaming = BundledAssetGroupSchema.BundleNamingStyle.NoHash; bundledAssetGroupSchema.BundleNaming = BundledAssetGroupSchema.BundleNamingStyle.NoHash; AddressableAssetSettingsDefaultObject.Settings.profileSettings.SetValue(group.Settings.activeProfileId, "LocalBuildPath", "[ThunderRoad.ModBuilder.buildPath]"); AddressableAssetSettingsDefaultObject.Settings.profileSettings.SetValue(group.Settings.activeProfileId, "LocalLoadPath", (toDefault ? "{ThunderRoad.FileManager.aaDefaultPath}/" : "{ThunderRoad.FileManager.aaModPath}/") + exportFolderName); // Set builtin shader to export folder name to avoid duplicates AddressableAssetSettingsDefaultObject.Settings.ShaderBundleNaming = UnityEditor.AddressableAssets.Build.ShaderBundleNaming.Custom; AddressableAssetSettingsDefaultObject.Settings.ShaderBundleCustomNaming = exportFolderName; AddressableAssetSettingsDefaultObject.Settings.BuildRemoteCatalog = true; /* TODO: OBB support (zip file uncompressed and adb push to obb folder) * AddressableAssetSettingsDefaultObject.Settings.profileSettings.SetValue(group.Settings.activeProfileId, "LocalLoadPath", "{ThunderRoad.FileManager.obbPath}/" + exportFolderName + "{ThunderRoad.FileManager.obbPathEnd}"); */ } } } AssetDatabase.Refresh(); AssetDatabase.SaveAssets(); // Build if (behaviour == Action.BuildAndExport || behaviour == Action.BuildOnly) { Debug.Log("Build path is: " + buildPath); if (OnBuildEvent != null) { OnBuildEvent.Invoke(EventTime.OnStart); } // Clean build path if (Directory.Exists(buildPath)) { foreach (string filePath in Directory.GetFiles(buildPath, "*.*", SearchOption.AllDirectories)) { File.Delete(filePath); } } BuildCache.PurgeCache(true); AddressableAssetSettings.CleanPlayerContent(); AddressableAssetSettings.CleanPlayerContent(AddressableAssetSettingsDefaultObject.Settings.ActivePlayerDataBuilder); AddressableAssetSettings.BuildPlayerContent(); Debug.Log("Build done"); if (OnBuildEvent != null) { OnBuildEvent.Invoke(EventTime.OnEnd); } } // Export if (behaviour == Action.BuildAndExport || behaviour == Action.ExportOnly) { if (exportTo == ExportTo.Game || exportTo == ExportTo.Project) { // Get paths string buildFullPath = Path.Combine(Directory.GetCurrentDirectory(), buildPath); string catalogFullPath = Path.Combine(Directory.GetCurrentDirectory(), catalogPath); string destinationAssetsPath = ""; string destinationCatalogPath = ""; if (exportTo == ExportTo.Project) { destinationAssetsPath = Path.Combine(projectPath, buildPath); destinationCatalogPath = Path.Combine(projectPath, catalogPath); } else if (exportTo == ExportTo.Game) { if (toDefault) { destinationAssetsPath = destinationCatalogPath = Path.Combine(gamePath, gameName + "_Data/StreamingAssets/Default", exportFolderName); } else { destinationAssetsPath = destinationCatalogPath = Path.Combine(gamePath, gameName + "_Data/StreamingAssets/Mods", exportFolderName); } } // Create folders if needed if (!File.Exists(destinationAssetsPath)) { Directory.CreateDirectory(destinationAssetsPath); } if (!File.Exists(destinationCatalogPath)) { Directory.CreateDirectory(destinationCatalogPath); } // Clean destination path if (cleanDestination) { foreach (string filePath in Directory.GetFiles(destinationAssetsPath, "*.*", SearchOption.AllDirectories)) { File.Delete(filePath); } if (exportTo == ExportTo.Game) { foreach (string filePath in Directory.GetFiles(destinationCatalogPath, "*.*", SearchOption.AllDirectories)) { File.Delete(filePath); } } } else { foreach (string filePath in Directory.GetFiles(destinationAssetsPath, "catalog_*.json", SearchOption.AllDirectories)) { File.Delete(filePath); } foreach (string filePath in Directory.GetFiles(destinationAssetsPath, "catalog_*.hash", SearchOption.AllDirectories)) { File.Delete(filePath); } if (exportTo == ExportTo.Game) { foreach (string filePath in Directory.GetFiles(destinationCatalogPath, "catalog_*.json", SearchOption.AllDirectories)) { File.Delete(filePath); } foreach (string filePath in Directory.GetFiles(destinationCatalogPath, "catalog_*.hash", SearchOption.AllDirectories)) { File.Delete(filePath); } } } // Copy addressable assets to destination path CopyDirectory(buildFullPath, destinationAssetsPath); Debug.Log("Copied addressable asset folder " + buildFullPath + " to " + destinationAssetsPath); if (exportTo == ExportTo.Game) { // Copy json catalog to destination path CopyDirectory(catalogFullPath, destinationCatalogPath); Debug.Log("Copied catalog folder " + catalogFullPath + " to " + destinationCatalogPath); // Copy plugin dll if any string dllPath = Path.Combine("BuildStaging", "Plugins", exportFolderName) + "/bin/Release/netstandard2.0/" + exportFolderName + ".dll"; if (File.Exists(dllPath)) { File.Copy(dllPath, destinationCatalogPath + "/" + exportFolderName + ".dll", true); Debug.Log("Copied dll " + dllPath + " to " + destinationCatalogPath); } } } if ((exportTo == ExportTo.Game) && runGameAfterBuild) { System.Diagnostics.Process process = new System.Diagnostics.Process(); process.StartInfo.FileName = Path.Combine(gamePath, gameName + ".exe"); process.StartInfo.Arguments = runGameArguments; process.Start(); Debug.Log("Start game: " + process.StartInfo.FileName + " " + process.StartInfo.Arguments); } #if PrivateSDK if (exportTo == ExportTo.Android) { string buildFullPath = Path.Combine(Directory.GetCurrentDirectory(), "BuildStaging", "AddressableAssets", "Android"); System.Diagnostics.Process process = new System.Diagnostics.Process(); process.StartInfo.FileName = GetAdbPath(); string destinationPath = "/sdcard/Android/data/com.Warpfrog." + gameName + "/files/mods/" + exportFolderName; process.StartInfo.Arguments = "push " + buildFullPath + "/. " + destinationPath; // for default: obb : /sdcard/Android/obb/" + PlayerSettings.applicationIdentifier + "/main.1.com.Warpfrog.BladeAndSorcery.obb"); process.Start(); process.WaitForExit(); Debug.Log(GetAdbPath() + " " + process.StartInfo.Arguments); if (runGameAfterBuild) { process = new System.Diagnostics.Process(); process.StartInfo.FileName = GetAdbPath(); process.StartInfo.Arguments = "shell am start -n " + PlayerSettings.applicationIdentifier + "/com.unity3d.player.UnityPlayerActivity"; process.Start(); Debug.Log("Start game: " + process.StartInfo.FileName + " " + process.StartInfo.Arguments); } } #endif Debug.Log("Export done"); } // The end System.Media.SystemSounds.Asterisk.Play(); }
private void OnGUI() { GUILayout.Space(5); EditorGUILayout.LabelField("", GUI.skin.horizontalSlider); BuildProfileGUI(); EditorGUILayout.LabelField("", GUI.skin.horizontalSlider); ExportFolderGUI(); EditorGUILayout.LabelField("", GUI.skin.horizontalSlider); if (action == Action.BuildAndExport || action == Action.BuildOnly) { GUILayout.Label(new GUIContent("Included addressable group(s)"), new GUIStyle("BoldLabel")); GUILayout.Space(5); if (GUILayout.Button("Refresh available groups") && AddressableAssetSettingsDefaultObject.Settings != null) { foreach (AddressableAssetGroup aaGroup in GetAllInstances <AddressableAssetGroup>()) { if (AddressableAssetSettingsDefaultObject.Settings.groups.Contains(aaGroup)) { continue; } AddressableAssetSettingsDefaultObject.Settings.groups.Add(aaGroup); } } GUILayout.Space(5); if (GUILayout.Button("Check/uncheck all")) { CheckAll(currentCheck); currentCheck = !currentCheck; } scrollPos = EditorGUILayout.BeginScrollView(scrollPos, GUILayout.Width(400), GUILayout.Height(300)); if (AddressableAssetSettingsDefaultObject.Settings != null) { foreach (AddressableAssetGroup group in AddressableAssetSettingsDefaultObject.Settings.groups) { if (group == null) { continue; } BundledAssetGroupSchema bundledAssetGroupSchema = group.GetSchema <BundledAssetGroupSchema>(); if (bundledAssetGroupSchema != null) { EditorGUILayout.BeginHorizontal(); bool newInclude = EditorGUILayout.Toggle(bundledAssetGroupSchema.IncludeInBuild, GUILayout.MaxWidth(20)); if (newInclude != bundledAssetGroupSchema.IncludeInBuild) { bundledAssetGroupSchema.IncludeInBuild = newInclude; EditorUtility.SetDirty(group); } EditorGUI.BeginDisabledGroup(true); EditorGUILayout.ObjectField(group, typeof(AddressableAssetGroup), false, GUILayout.MaxWidth(500)); EditorGUI.EndDisabledGroup(); EditorGUILayout.EndHorizontal(); } } } EditorGUILayout.EndScrollView(); } if (action == Action.BuildAndExport || action == Action.ExportOnly) { if (action == Action.BuildAndExport) { EditorGUILayout.LabelField("", GUI.skin.horizontalSlider); } ExportToGUI(); } EditorGUILayout.LabelField("", GUI.skin.horizontalSlider); if (GUILayout.Button(action == Action.BuildOnly ? "Build" : (action == Action.ExportOnly ? "Export" : "Build and export"))) { Build(action); } }
public static IEnumerator PackageWorlds(int packageMode, int releaseChannel, bool allWorlds, bool allTargets, bool force = false, bool linuxOnly = false) { uploadPossible = false; packagingInProgress = true; packagingSuccessful = false; try { string[] worldsToBuild = allWorlds ? GetWorldPaths() : GetWorldsToBuild(packageMode); if (worldsToBuild.Length == 0) { yield break; } string resultFolder = Application.dataPath + "/../traVRsal/"; BuildTarget mainTarget = linuxOnly || Application.platform == RuntimePlatform.LinuxEditor ? BuildTarget.StandaloneLinux64 : BuildTarget.StandaloneWindows64; CreateLockFile(); ConvertTileMaps(); CreateAddressableSettings(!allTargets, releaseChannel); EditorUserBuildSettings.androidBuildSubtarget = MobileTextureSubtarget.ASTC; EditorUserBuildSettings.selectedStandaloneTarget = mainTarget; PlayerSettings.SetScriptingBackend(BuildTargetGroup.Standalone, ScriptingImplementation.Mono2x); // Linux can only be built with Mono on Windows AddressableAssetSettings.CleanPlayerContent(); AssetDatabase.SaveAssets(); if (Directory.Exists(GetServerDataPath()) && (packageMode == 0 || allWorlds)) { Directory.Delete(GetServerDataPath(), true); } // set build targets List <Tuple <BuildTargetGroup, BuildTarget> > targets = new List <Tuple <BuildTargetGroup, BuildTarget> >(); if (allTargets) { targets.Add(new Tuple <BuildTargetGroup, BuildTarget>(BuildTargetGroup.Android, BuildTarget.Android)); // set windows/linux last so that we can continue with editor iterations normally right afterwards if (Application.platform == RuntimePlatform.LinuxEditor) { targets.Add(new Tuple <BuildTargetGroup, BuildTarget>(BuildTargetGroup.Standalone, BuildTarget.StandaloneWindows64)); targets.Add(new Tuple <BuildTargetGroup, BuildTarget>(BuildTargetGroup.Standalone, BuildTarget.StandaloneLinux64)); } else { if (linuxSupport) { targets.Add(new Tuple <BuildTargetGroup, BuildTarget>(BuildTargetGroup.Standalone, BuildTarget.StandaloneLinux64)); } targets.Add(new Tuple <BuildTargetGroup, BuildTarget>(BuildTargetGroup.Standalone, BuildTarget.StandaloneWindows64)); } } else { targets.Add(new Tuple <BuildTargetGroup, BuildTarget>(BuildTargetGroup.Standalone, mainTarget)); } // update world content foreach (string dir in worldsToBuild) { string worldName = Path.GetFileName(dir); if (!UpdateWorldData(worldName)) { yield break; } } // iterate over all supported platforms foreach (Tuple <BuildTargetGroup, BuildTarget> target in targets) { EditorUserBuildSettings.SwitchActiveBuildTarget(target.Item1, target.Item2); // build each world individually AddressableAssetSettings settings = AddressableAssetSettingsDefaultObject.GetSettings(true); foreach (string dir in worldsToBuild) { string worldName = Path.GetFileName(dir); string serverDir = GetServerDataPath() + "/Worlds/" + Path.GetFileName(dir); if (!allTargets && Directory.Exists(resultFolder + worldName)) { Directory.Delete(resultFolder + worldName, true); } if (packageMode == 1 && !allWorlds && Directory.Exists(serverDir)) { Directory.Delete(serverDir, true); } settings.activeProfileId = settings.profileSettings.GetProfileId(worldName); settings.groups.ForEach(group => { if (group.ReadOnly) { return; } group.GetSchema <BundledAssetGroupSchema>().IncludeInBuild = group.name == worldName; // default group ensures there is no accidental local default group resulting in local paths being baked into addressable for shaders if (group.name == worldName && group.CanBeSetAsDefault()) { settings.DefaultGroup = group; } }); BundledAssetGroupSchema schema = settings.groups.First(group => @group.name == worldName).GetSchema <BundledAssetGroupSchema>(); settings.RemoteCatalogBuildPath = schema.BuildPath; settings.RemoteCatalogLoadPath = schema.LoadPath; settings.ShaderBundleCustomNaming = worldName; AddressableAssetSettings.BuildPlayerContent(); } } CreateAddressableSettings(!allTargets, releaseChannel); // do again to have clean build state, as some settings were messed with while building RenameCatalogs(); packagingSuccessful = true; } catch (Exception e) { packagingInProgress = false; EditorUtility.DisplayDialog("Error", $"Packaging could not be completed. Error: {e.Message}", "Close"); yield break; } if (dirWatcher != null) { dirWatcher.ClearAffected(); // only do at end, since during build might cause false positives } else { CreateDirWatcher(); // can happen after initial project creation } RemoveLockFile(); packagingInProgress = false; Debug.Log("Packaging completed successfully."); }
private static void CreateAddressableSettings(bool localMode, int releaseChannel) { AddressableAssetSettings settings = AddressableAssetSettingsDefaultObject.GetSettings(true); settings.ActivePlayModeDataBuilderIndex = localMode ? 0 : 2; settings.BuildRemoteCatalog = true; settings.DisableCatalogUpdateOnStartup = true; settings.ContiguousBundles = true; settings.IgnoreUnsupportedFilesInBuild = true; settings.ShaderBundleNaming = ShaderBundleNaming.Custom; // don't include built-in data, causes shader issues settings.groups.ForEach(g => { PlayerDataGroupSchema schema = g.GetSchema <PlayerDataGroupSchema>(); if (schema != null) { schema.IncludeBuildSettingsScenes = false; schema.IncludeResourcesFolders = false; } }); // setup profiles AddressableAssetProfileSettings profile = settings.profileSettings; // activate and (re)group assets foreach (string dir in GetWorldPaths()) { string worldName = Path.GetFileName(dir); bool isBase = worldName == "Base"; // create one profile per world string profileId = profile.GetProfileId(worldName); if (string.IsNullOrEmpty(profileId)) { profileId = profile.AddProfile(worldName, settings.activeProfileId); } string guid = AssetDatabase.AssetPathToGUID($"Assets/Worlds/{worldName}"); // create group if non-existent AddressableAssetGroup group = settings.groups.FirstOrDefault(g => g.name == worldName); if (group == null) { group = CreateAssetGroup <BundledAssetGroupSchema>(settings, worldName); } if (group.CanBeSetAsDefault()) { settings.DefaultGroup = group; // default group ensures there is no accidental local default group resulting in local paths being baked into addressable for shaders } // set correct path AddressableAssetEntry entry = settings.CreateOrMoveEntry(guid, group); entry.SetAddress($"Worlds/{worldName}"); // set variables string localRoot = Application.dataPath + $"/../traVRsal/{worldName}/[BuildTarget]"; string remoteTarget = null; switch (releaseChannel) { case 0: remoteTarget = AWSUtil.S3CDNRoot_Live; break; case 1: remoteTarget = AWSUtil.S3CDNRoot_Beta; break; case 2: remoteTarget = AWSUtil.S3CDNRoot_Alpha; break; } profile.SetValue(profileId, AddressableAssetSettings.kLocalBuildPath, localRoot); profile.SetValue(profileId, AddressableAssetSettings.kLocalLoadPath, localRoot); profile.SetValue(profileId, AddressableAssetSettings.kRemoteBuildPath, $"ServerData/Worlds/{worldName}/[BuildTarget]"); profile.SetValue(profileId, AddressableAssetSettings.kRemoteLoadPath, $"{remoteTarget}Worlds/{worldName}/[BuildTarget]"); // ensure correct group settings BundledAssetGroupSchema groupSchema = group.GetSchema <BundledAssetGroupSchema>(); groupSchema.UseAssetBundleCache = true; groupSchema.UseAssetBundleCrc = false; groupSchema.IncludeInBuild = isBase; groupSchema.RetryCount = 3; groupSchema.BundleNaming = BundledAssetGroupSchema.BundleNamingStyle.NoHash; // hash to disambiguate identically named files yields same error messages, e.g. standard shaders groupSchema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogether; groupSchema.Compression = BundledAssetGroupSchema.BundleCompressionMode.LZ4; groupSchema.BuildPath.SetVariableByName(settings, localMode ? AddressableAssetSettings.kLocalBuildPath : AddressableAssetSettings.kRemoteBuildPath); groupSchema.LoadPath.SetVariableByName(settings, localMode ? AddressableAssetSettings.kLocalLoadPath : AddressableAssetSettings.kRemoteLoadPath); } }
private IEnumerator PackageLevels(bool allLevels, bool allTargets) { uploadPossible = false; packagingInProgress = true; packagingSuccessful = false; try { string[] levelsToBuild = allLevels ? GetLevelPaths() : GetLevelsToBuild(); if (levelsToBuild.Length == 0) { yield break; } CreateLockFile(); ConvertTileMaps(); CreateAddressableSettings(!allTargets); EditorUserBuildSettings.androidBuildSubtarget = MobileTextureSubtarget.Generic; // FIXME: ASTC resulting in pink shaders as of 2019.4+ EditorUserBuildSettings.selectedStandaloneTarget = BuildTarget.StandaloneWindows64; AddressableAssetSettings.CleanPlayerContent(); if (Directory.Exists(GetServerDataPath()) && (packageMode == 0 || allLevels)) { Directory.Delete(GetServerDataPath(), true); } // set build targets List <BuildTarget> targets = new List <BuildTarget>(); if (!debugMode) { targets.Add(BuildTarget.Android); } targets.Add(BuildTarget.StandaloneWindows64); // set windows last so that we can continue with editor iterations normally right afterwards // build each level individually AddressableAssetSettings settings = AddressableAssetSettingsDefaultObject.GetSettings(true); foreach (string dir in levelsToBuild) { string levelName = Path.GetFileName(dir); string serverDir = GetServerDataPath() + "/Levels/" + Path.GetFileName(dir); if (packageMode == 1 && !allLevels && Directory.Exists(serverDir)) { Directory.Delete(serverDir, true); } settings.activeProfileId = settings.profileSettings.GetProfileId(levelName); settings.groups.ForEach(group => { if (group.ReadOnly) { return; } group.GetSchema <BundledAssetGroupSchema>().IncludeInBuild = group.name == levelName; }); BundledAssetGroupSchema schema = settings.groups.Where(group => group.name == levelName).First().GetSchema <BundledAssetGroupSchema>(); settings.RemoteCatalogBuildPath = schema.BuildPath; settings.RemoteCatalogLoadPath = schema.LoadPath; if (allTargets) { // iterate over all supported platforms foreach (BuildTarget target in targets) { EditorUserBuildSettings.SwitchActiveBuildTarget(target); AddressableAssetSettings.BuildPlayerContent(); } } else { // build only for currently active target AddressableAssetSettings.BuildPlayerContent(); } } CreateAddressableSettings(!allTargets); // do again to have clean build state, as some settings were messed with while building RenameCatalogs(); packagingSuccessful = true; } catch (Exception e) { packagingInProgress = false; EditorUtility.DisplayDialog("Error", "Packaging could not be completed. Error: " + e.Message, "Close"); yield break; } dirWatcher.ClearAffected(); // only do at end, since during build might cause false positives RemoveLockFile(); packagingInProgress = false; Debug.Log("Packaging completed successfully."); }
private BuildLayout CreateBuildLayout() { LayoutLookupTables lookup = new LayoutLookupTables(); foreach (string bundleName in m_WriteData.FileToBundle.Values.Distinct()) { BuildLayout.Bundle bundle = new BuildLayout.Bundle(); bundle.Name = bundleName; string path = m_Parameters.GetOutputFilePathForIdentifier(bundle.Name); UnityEngine.BuildCompression compression = m_Parameters.GetCompressionForIdentifier(bundle.Name); bundle.FileSize = (ulong)new FileInfo(path).Length; bundle.Compression = compression.compression.ToString(); lookup.Bundles.Add(bundle.Name, bundle); } // create files foreach (KeyValuePair <string, string> fileBundle in m_WriteData.FileToBundle) { BuildLayout.Bundle bundle = lookup.Bundles[fileBundle.Value]; BuildLayout.File f = new BuildLayout.File(); f.Name = fileBundle.Key; WriteResult result = m_Results.WriteResults[f.Name]; foreach (ResourceFile rf in result.resourceFiles) { var sf = new BuildLayout.SubFile(); sf.IsSerializedFile = rf.serializedFile; sf.Name = rf.fileAlias; sf.Size = (ulong)new FileInfo(rf.fileName).Length; f.SubFiles.Add(sf); } bundle.Files.Add(f); lookup.Files.Add(f.Name, f); } // create assets foreach (KeyValuePair <GUID, List <string> > assetFile in m_WriteData.AssetToFiles) { BuildLayout.File file = lookup.Files[assetFile.Value[0]]; BuildLayout.ExplicitAsset a = new BuildLayout.ExplicitAsset(); a.Guid = assetFile.Key.ToString(); a.AssetPath = AssetDatabase.GUIDToAssetPath(a.Guid); file.Assets.Add(a); lookup.GuidToExplicitAsset.Add(a.Guid, a); } Dictionary <string, List <BuildLayout.DataFromOtherAsset> > guidToPulledInBuckets = new Dictionary <string, List <BuildLayout.DataFromOtherAsset> >(); foreach (BuildLayout.File file in lookup.Files.Values) { Dictionary <string, AssetBucket> buckets = new Dictionary <string, AssetBucket>(); WriteResult writeResult = m_Results.WriteResults[file.Name]; List <ObjectSerializedInfo> sceneObjects = new List <ObjectSerializedInfo>(); foreach (ObjectSerializedInfo info in writeResult.serializedObjects) { string sourceGuid = string.Empty; if (info.serializedObject.guid.Empty()) { if (info.serializedObject.filePath.Equals("temp:/assetbundle", StringComparison.OrdinalIgnoreCase)) { file.BundleObjectInfo = new BuildLayout.AssetBundleObjectInfo(); file.BundleObjectInfo.Size = info.header.size; continue; } else if (info.serializedObject.filePath.StartsWith("temp:/preloaddata", StringComparison.OrdinalIgnoreCase)) { file.PreloadInfoSize = (int)info.header.size; continue; } else if (info.serializedObject.filePath.StartsWith("temp:/", StringComparison.OrdinalIgnoreCase)) { sceneObjects.Add(info); continue; } else if (!string.IsNullOrEmpty(info.serializedObject.filePath)) { AssetBucket pathBucket = GetOrCreate(buckets, info.serializedObject.filePath.ToString()); pathBucket.isFilePathBucket = true; pathBucket.objs.Add(info); continue; } } AssetBucket bucket = GetOrCreate(buckets, info.serializedObject.guid.ToString()); bucket.objs.Add(info); } if (sceneObjects.Count > 0) { BuildLayout.ExplicitAsset sceneAsset = file.Assets.First(x => x.AssetPath.EndsWith(".unity")); AssetBucket bucket = GetOrCreate(buckets, sceneAsset.Guid); bucket.objs.AddRange(sceneObjects); } // Update buckets with a reference to their explicit asset file.Assets.ForEach(eAsset => { if (!buckets.TryGetValue(eAsset.Guid, out AssetBucket b)) { b = GetOrCreate(buckets, eAsset.Guid); // some assets might not pull in any objects } b.ExplictAsset = eAsset; }); // Create entries for buckets that are implicitly pulled in Dictionary <string, BuildLayout.DataFromOtherAsset> guidToOtherData = new Dictionary <string, BuildLayout.DataFromOtherAsset>(); foreach (AssetBucket bucket in buckets.Values.Where(x => x.ExplictAsset == null)) { string assetPath = bucket.isFilePathBucket ? bucket.guid : AssetDatabase.GUIDToAssetPath(bucket.guid); if (assetPath.EndsWith(".cs", StringComparison.OrdinalIgnoreCase) || assetPath.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) { file.MonoScriptCount++; file.MonoScriptSize += bucket.CalcObjectSize(); continue; } var otherData = new BuildLayout.DataFromOtherAsset(); otherData.AssetPath = assetPath; otherData.AssetGuid = bucket.guid; otherData.SerializedSize = bucket.CalcObjectSize(); otherData.StreamedSize = bucket.CalcStreamedSize(); otherData.ObjectCount = bucket.objs.Count; file.OtherAssets.Add(otherData); guidToOtherData[otherData.AssetGuid] = otherData; if (!guidToPulledInBuckets.TryGetValue(otherData.AssetGuid, out List <BuildLayout.DataFromOtherAsset> bucketList)) { bucketList = guidToPulledInBuckets[otherData.AssetGuid] = new List <BuildLayout.DataFromOtherAsset>(); } bucketList.Add(otherData); } // Add references foreach (BuildLayout.ExplicitAsset asset in file.Assets) { AssetBucket bucket = buckets[asset.Guid]; asset.SerializedSize = bucket.CalcObjectSize(); asset.StreamedSize = bucket.CalcStreamedSize(); IEnumerable <ObjectIdentifier> refs = null; if (m_DependencyData.AssetInfo.TryGetValue(new GUID(asset.Guid), out AssetLoadInfo info)) { refs = info.referencedObjects; } else { refs = m_DependencyData.SceneInfo[new GUID(asset.Guid)].referencedObjects; } foreach (string refGUID in refs.Select(x => x.guid.Empty() ? x.filePath : x.guid.ToString()).Distinct()) { if (guidToOtherData.TryGetValue(refGUID, out BuildLayout.DataFromOtherAsset dfoa)) { dfoa.ReferencingAssets.Add(asset); asset.InternalReferencedOtherAssets.Add(dfoa); } else if (buckets.TryGetValue(refGUID, out AssetBucket refBucket)) { asset.InternalReferencedExplicitAssets.Add(refBucket.ExplictAsset); } else if (lookup.GuidToExplicitAsset.TryGetValue(refGUID, out BuildLayout.ExplicitAsset refAsset)) { asset.ExternallyReferencedAssets.Add(refAsset); } } } } BuildLayout layout = new BuildLayout(); // This is the addressables section. Everything above could technically be moved to SBP. { AddressableAssetsBuildContext aaContext = (AddressableAssetsBuildContext)m_AaBuildContext; // Map from GUID to AddrssableAssetEntry Dictionary <string, AddressableAssetEntry> guidToEntry = aaContext.assetEntries.ToDictionary(x => x.guid, x => x); // create groups foreach (AddressableAssetGroup group in aaContext.Settings.groups) { var grp = new BuildLayout.Group(); grp.Name = group.Name; grp.Guid = group.Guid; foreach (AddressableAssetGroupSchema schema in group.Schemas) { var sd = new BuildLayout.SchemaData(); sd.Guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(schema)); sd.Type = schema.GetType().Name.ToString(); BundledAssetGroupSchema bSchema = schema as BundledAssetGroupSchema; if (bSchema != null) { sd.KvpDetails.Add(new Tuple <string, string>("PackingMode", bSchema.BundleMode.ToString())); sd.KvpDetails.Add(new Tuple <string, string>("Compression", bSchema.Compression.ToString())); } grp.Schemas.Add(sd); } lookup.GroupLookup.Add(group.Guid, grp); layout.Groups.Add(grp); } // go through all the bundles and put them in groups foreach (BuildLayout.Bundle b in lookup.Bundles.Values) { if (aaContext.bundleToImmediateBundleDependencies.TryGetValue(b.Name, out List <string> deps)) { b.Dependencies = deps.Select(x => lookup.Bundles[x]).Where(x => b != x).ToList(); } if (aaContext.bundleToExpandedBundleDependencies.TryGetValue(b.Name, out List <string> deps2)) { b.ExpandedDependencies = deps2.Select(x => lookup.Bundles[x]).Where(x => b != x).ToList(); } if (aaContext.bundleToAssetGroup.TryGetValue(b.Name, out string grpName)) { lookup.GroupLookup[grpName].Bundles.Add(b); } else { layout.BuiltInBundles.Add(b); } } // Apply the addressable name to the asset foreach (BuildLayout.ExplicitAsset a in BuildLayoutHelpers.EnumerateAssets(layout)) { if (guidToEntry.TryGetValue(a.Guid, out AddressableAssetEntry entry)) { a.AddressableName = entry.address; } } // The addressables build script can rename the bundles foreach (BuildLayout.Bundle b in BuildLayoutHelpers.EnumerateBundles(layout)) { if (m_BundleNameRemap.TryGetValue(b.Name, out string newName)) { b.Name = newName; } } } return(layout); }
private void CreateAddressableSettings(bool localMode) { AddressableAssetSettings settings = AddressableAssetSettingsDefaultObject.GetSettings(true); settings.ActivePlayModeDataBuilderIndex = localMode ? 0 : 2; settings.BuildRemoteCatalog = true; settings.DisableCatalogUpdateOnStartup = true; // don't include built-in data, causes shader issues settings.groups.ForEach(g => { PlayerDataGroupSchema schema = g.GetSchema <PlayerDataGroupSchema>(); if (schema != null) { schema.IncludeBuildSettingsScenes = false; schema.IncludeResourcesFolders = false; } }); // setup profiles AddressableAssetProfileSettings profile = settings.profileSettings; // activate and (re)group assets foreach (string dir in GetLevelPaths()) { string levelName = Path.GetFileName(dir); bool isBase = levelName == "Base"; // create one profile per level string profileId = profile.GetProfileId(levelName); if (string.IsNullOrEmpty(profileId)) { profileId = profile.AddProfile(levelName, settings.activeProfileId); } string guid = AssetDatabase.AssetPathToGUID($"Assets/Levels/{levelName}"); // create group if non-existent AddressableAssetGroup group = settings.groups.Where(g => g.name == levelName).FirstOrDefault(); if (group == null) { group = CreateAssetGroup <BundledAssetGroupSchema>(settings, levelName); } // set correct path AddressableAssetEntry entry = settings.CreateOrMoveEntry(guid, group); entry.SetAddress($"Levels/{levelName}"); // set variables string localRoot = Application.dataPath + $"/../Library/com.unity.addressables/aa/Windows/Levels/{levelName}/[BuildTarget]"; profile.SetValue(profileId, AddressableAssetSettings.kLocalBuildPath, localRoot); profile.SetValue(profileId, AddressableAssetSettings.kLocalLoadPath, localRoot); profile.SetValue(profileId, AddressableAssetSettings.kRemoteBuildPath, $"ServerData/Levels/{levelName}/[BuildTarget]"); profile.SetValue(profileId, AddressableAssetSettings.kRemoteLoadPath, $"{AWSUtil.S3Root}Levels/{levelName}/[BuildTarget]"); // ensure correct group settings BundledAssetGroupSchema groupSchema = group.GetSchema <BundledAssetGroupSchema>(); groupSchema.UseAssetBundleCache = true; groupSchema.UseAssetBundleCrc = false; groupSchema.IncludeInBuild = isBase ? true : false; groupSchema.BundleNaming = BundledAssetGroupSchema.BundleNamingStyle.NoHash; // hash to disimbiguate identically named files yields same error messages, e.g. standard shaders groupSchema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogether; groupSchema.Compression = BundledAssetGroupSchema.BundleCompressionMode.LZ4; groupSchema.BuildPath.SetVariableByName(settings, localMode ? AddressableAssetSettings.kLocalBuildPath : AddressableAssetSettings.kRemoteBuildPath); groupSchema.LoadPath.SetVariableByName(settings, localMode ? AddressableAssetSettings.kLocalLoadPath : AddressableAssetSettings.kRemoteLoadPath); } }
public static void AddFileToAddressables() { AddressablesRules rules = new AddressablesRules(); Dictionary <string, BuildAddressablesData> bundles = rules.GetBuilds(); AddressableAssetSettings aaSettings = AddressableAssetSettingsDefaultObject.GetSettings(false); AddressableAssetGroup group = null; //清理错误group for (int i = aaSettings.groups.Count - 1; i >= 0; i--) { var g = aaSettings.groups[i]; if (g == null || g.entries.Count == 0) { aaSettings.RemoveGroup(g); g = null; continue; } // // if (g != null) // { // g.Name = $"{g.Name}_delete"; // } } foreach (string key in bundles.Keys) { group = aaSettings.groups.Find(x => x.Name == bundles[key].GroupName); if (group == null) { group = aaSettings.CreateGroup(bundles[key].GroupName, false, false, false, null); } BundledAssetGroupSchema schema = group.GetSchema <BundledAssetGroupSchema>(); if (schema == null) { schema = group.AddSchema <BundledAssetGroupSchema>(); } ContentUpdateGroupSchema contentUpdateGroupSchema = group.GetSchema <ContentUpdateGroupSchema>(); if (contentUpdateGroupSchema == null) { contentUpdateGroupSchema = group.AddSchema <ContentUpdateGroupSchema>(); } schema.Compression = BundledAssetGroupSchema.BundleCompressionMode.LZ4; if (bundles[key].packageType == "PackSeparately") { schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackSeparately; } else if (bundles[key].packageType == "PackTogether") { schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogether; } else if (bundles[key].packageType == "PackTogetherByLabel") { schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogetherByLabel; } schema.IncludeInBuild = true; schema.UseAssetBundleCache = true; schema.UseAssetBundleCrc = false; schema.UseAssetBundleCrcForCachedBundles = false; if (bundles[key].ResType == "online") { schema.BuildPath.SetVariableByName(group.Settings, AddressableAssetSettings.kRemoteBuildPath); schema.LoadPath.SetVariableByName(group.Settings, AddressableAssetSettings.kRemoteLoadPath); schema.BundleNaming = BundledAssetGroupSchema.BundleNamingStyle.AppendHash; schema.UseAssetBundleCrc = true; contentUpdateGroupSchema.StaticContent = false; } else { schema.BuildPath.SetVariableByName(group.Settings, AddressableAssetSettings.kLocalBuildPath); schema.LoadPath.SetVariableByName(group.Settings, AddressableAssetSettings.kLocalLoadPath); schema.BundleNaming = BundledAssetGroupSchema.BundleNamingStyle.NoHash; contentUpdateGroupSchema.StaticContent = true; } } foreach (string key in bundles.Keys) { int count = 0; int MaxCount = bundles[key].entitys.Count; group = aaSettings.groups.Find(x => x.Name == bundles[key].GroupName); foreach (string entitysKey in bundles[key].entitys.Keys) { count++; if (count % 3 == 0) { if (UnityEditor.EditorUtility.DisplayCancelableProgressBar(string.Format("Collecting... [{0}/{1}]", count, MaxCount), entitysKey, count * 1f / MaxCount)) { break; } } string guid = AssetDatabase.AssetPathToGUID(bundles[key].entitys[entitysKey].filestring); AddressableAssetEntry entity = aaSettings.CreateOrMoveEntry(guid, group); entity.SetAddress(entitysKey); for (int i = 0; i < bundles[key].Lable.Length; i++) { if (bundles[key].Lable[i].Contains("#")) { if (!string.IsNullOrEmpty(bundles[key].entitys[entitysKey].folderlabel)) { aaSettings.AddLabel(bundles[key].entitys[entitysKey].folderlabel); entity.SetLabel(bundles[key].entitys[entitysKey].folderlabel, true); } } else { aaSettings.AddLabel(bundles[key].Lable[i]); entity.SetLabel(bundles[key].Lable[i], true); } } } } // for (int i = aaSettings.groups.Count - 1; i >= 0; i--) // { // var g = aaSettings.groups[i]; // if (g == null || g.entries.Count == 0) // { // aaSettings.RemoveGroup(g); // g = null; // continue; // } // // if (g != null) // { // if (g.Name.Contains("_delete")) // { // aaSettings.RemoveGroup(g); // g = null; // } // } // } UnityEditor.EditorUtility.ClearProgressBar(); }
public static void AddFileToAddressables() { AddressablesRules rules = new AddressablesRules(); Dictionary <string, BuildAddressablesData> bundles = rules.GetBuilds(); AddressableAssetSettings aaSettings = AddressableAssetSettingsDefaultObject.GetSettings(false); AddressableAssetGroup group = null; //清理重名group foreach (string key in bundles.Keys) { group = aaSettings.groups.Find(x => x.Name == bundles[key].GroupName); if (group != null) { aaSettings.RemoveGroup(group); group = null; } } foreach (string key in bundles.Keys) { group = aaSettings.groups.Find(x => x.Name == bundles[key].GroupName); if (group == null) { if (bundles[key].ResType == "online") { group = aaSettings.CreateGroup(bundles[key].GroupName, false, false, false, null); BundledAssetGroupSchema schema = group.AddSchema <BundledAssetGroupSchema>(); schema.Compression = BundledAssetGroupSchema.BundleCompressionMode.LZ4; if (bundles[key].packageType == "PackSeparately") { schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackSeparately; } else if (bundles[key].packageType == "PackTogether") { schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogether; } else if (bundles[key].packageType == "PackTogetherByLabel") { schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogetherByLabel; } schema.BuildPath.SetVariableByName(group.Settings, AddressableAssetSettings.kRemoteBuildPath); schema.LoadPath.SetVariableByName(group.Settings, AddressableAssetSettings.kRemoteLoadPath); schema.UseAssetBundleCache = true; schema.UseAssetBundleCrc = true; ContentUpdateGroupSchema contentUpdateGroupSchema = group.AddSchema <ContentUpdateGroupSchema>(); contentUpdateGroupSchema.StaticContent = false; group = null; } else { group = aaSettings.CreateGroup(bundles[key].GroupName, false, false, false, null); BundledAssetGroupSchema schema = group.AddSchema <BundledAssetGroupSchema>(); schema.Compression = BundledAssetGroupSchema.BundleCompressionMode.Uncompressed; if (bundles[key].packageType == "PackSeparately") { schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackSeparately; } else if (bundles[key].packageType == "PackTogether") { schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogether; } else if (bundles[key].packageType == "PackTogetherByLabel") { schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogetherByLabel; } if (bundles[key].canUpdate) { ContentUpdateGroupSchema contentUpdateGroupSchema = group.AddSchema <ContentUpdateGroupSchema>(); contentUpdateGroupSchema.StaticContent = false; } schema.UseAssetBundleCache = true; schema.UseAssetBundleCrc = true; group = null; } } } foreach (string key in bundles.Keys) { int count = 0; int MaxCount = bundles[key].entitys.Count; group = aaSettings.groups.Find(x => x.Name == bundles[key].GroupName); foreach (string entitysKey in bundles[key].entitys.Keys) { count++; if (count % 3 == 0) { if (UnityEditor.EditorUtility.DisplayCancelableProgressBar( string.Format("Collecting... [{0}/{1}]", count, MaxCount), entitysKey, count * 1f / MaxCount)) { break; } } string guid = AssetDatabase.AssetPathToGUID(bundles[key].entitys[entitysKey]); AddressableAssetEntry entity = aaSettings.CreateOrMoveEntry(guid, group); entity.SetAddress(entitysKey); for (int i = 0; i < bundles[key].Lable.Length; i++) { aaSettings.AddLabel(bundles[key].Lable[i]); entity.SetLabel(bundles[key].Lable[i], true); } } } UnityEditor.EditorUtility.ClearProgressBar(); }