Good day!
I have a project set up using Addressables for multiple platforms (Windows, iOS, and Android). However, I have to switch platforms individually and then build Addressables for each one, which is very time-consuming. I’m looking for an automated way to handle this process. I created an editor script to switch between different platforms and build Addressables, but the script seems to have some issues—it breaks in the middle and throws errors. If anyone has a workaround for this, I would greatly appreciate your help.
Editor Script:
using UnityEngine;
using UnityEditor;
using UnityEditor.Compilation;
using UnityEditor.AddressableAssets.Settings;
using UnityEditor.AddressableAssets;
using System.Collections;
using System.Collections.Generic;
using UnityEditor.AddressableAssets.Build;
public class BuildEditor
{
public enum PLATFORM { WINDOWS, ANDROID, IOS }
public static PLATFORM CURRENT_PLATFORM = PLATFORM.WINDOWS;
private static bool isWaitingForPlatformSwitch = false;
private static bool isWaitingForCompilation = false;
private static Queue<PLATFORM> platformQueue = new Queue<PLATFORM>();
[MenuItem("Tools/GlobalBuild")]
public static void BuildGlobal()
{
platformQueue.Enqueue(PLATFORM.ANDROID);
platformQueue.Enqueue(PLATFORM.IOS);
platformQueue.Enqueue(PLATFORM.WINDOWS);
ProcessNextPlatform();
}
private static void ProcessNextPlatform()
{
if (platformQueue.Count > 0)
{
CURRENT_PLATFORM = platformQueue.Dequeue();
Debug.Log("Processing platform: " + CURRENT_PLATFORM);
switch (CURRENT_PLATFORM)
{
case PLATFORM.ANDROID:
SetPlatformAndroid();
break;
case PLATFORM.IOS:
SetPlatformIOS();
break;
case PLATFORM.WINDOWS:
SetPlatformWindows();
break;
}
}
else
{
Debug.Log("Platform build process completed.");
}
}
[MenuItem("Tools/Build/Windows")]
public static void SetPlatformWindows()
{
UpdateConfigsToPC();
SwitchPlatform(BuildTargetGroup.Standalone, BuildTarget.StandaloneWindows64);
}
[MenuItem("Tools/Build/IOS")]
public static void SetPlatformIOS()
{
UpdateConfigsToMobile();
SwitchPlatform(BuildTargetGroup.iOS, BuildTarget.iOS);
}
[MenuItem("Tools/Build/Android")]
public static void SetPlatformAndroid()
{
UpdateConfigsToMobile();
SwitchPlatform(BuildTargetGroup.Android, BuildTarget.Android);
}
private static BuildTarget targetBuildTarget;
private static void SwitchPlatform(BuildTargetGroup targetGroup, BuildTarget buildTarget)
{
if (EditorUserBuildSettings.activeBuildTarget != buildTarget)
{
Debug.Log($"Switching platform to {buildTarget}...");
isWaitingForPlatformSwitch = true;
targetBuildTarget = buildTarget; // Store the target build target for checking after switching
// Trigger platform switch
EditorUserBuildSettings.SwitchActiveBuildTarget(targetGroup, buildTarget);
// Register update callback to wait for platform switch completion
EditorApplication.update += WaitForPlatformSwitch;
}
else
{
// Platform is already set, validate Addressable settings and build Addressables
ValidateAndBuildAddressables();
}
}
private static void WaitForPlatformSwitch()
{
// Check if the platform switch is complete by comparing the active build target with the target build target
if (EditorUserBuildSettings.activeBuildTarget == targetBuildTarget)
{
Debug.Log("Platform switch complete.");
isWaitingForPlatformSwitch = false;
EditorApplication.update -= WaitForPlatformSwitch;
// After platform switch, validate Addressable settings and build Addressables
ValidateAndBuildAddressables();
}
}
// Method to validate Addressable settings and trigger Addressable build
private static void ValidateAndBuildAddressables()
{
if (AddressableAssetSettingsDefaultObject.Settings == null)
{
Debug.LogError("Addressable settings are null. Make sure Addressable settings are properly configured before building.");
return;
}
// Ensure Addressable groups are properly configured
if (AddressableAssetSettingsDefaultObject.Settings.groups.Count == 0)
{
Debug.LogError("No Addressable groups are configured. Please configure Addressable groups before building.");
return;
}
// At this point, Addressable settings are valid. Proceed to build Addressables.
BuildAddressables();
}
public static void BuildAddressables()
{
if (isWaitingForPlatformSwitch)
{
Debug.Log("Waiting for platform switch to complete...");
return;
}
if (EditorApplication.isCompiling)
{
if (!isWaitingForCompilation)
{
Debug.Log("Waiting for compilation to finish...");
isWaitingForCompilation = true;
CompilationPipeline.compilationFinished += OnCompilationFinished;
}
return;
}
//PerformAddressablesBuild();
}
private static void OnCompilationFinished(object obj)
{
Debug.Log("Compilation finished. Proceeding to build Addressables...");
isWaitingForCompilation = false;
CompilationPipeline.compilationFinished -= OnCompilationFinished;
PerformAddressablesBuild();
}
private static void PerformAddressablesBuild()
{
Debug.Log("Building Addressables for platform: " + EditorUserBuildSettings.activeBuildTarget);
// Build Addressables
AddressableAssetSettings.CleanPlayerContent();
try
{
BuildAddressablesWithProgress();
// AddressableAssetSettings.BuildPlayerContent();
Debug.Log("Building Addressables DONE!");
// After successful Addressables build, move to the next platform (if applicable)
ProcessNextPlatform();
}
catch (System.Exception ex)
{
Debug.LogError("Addressables build failed with an exception: " + ex.Message);
}
}
public static void UpdateConfigsToMobile()
{
string[] guids = AssetDatabase.FindAssets("t:SceneConfig");
foreach (string guid in guids)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
SceneConfig config = AssetDatabase.LoadAssetAtPath<SceneConfig>(path);
if (config != null)
{
config.CurrentPlatform = SceneConfig.Platform.MOBILE;
EditorUtility.SetDirty(config);
}
}
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
Debug.Log("Updated all SceneConfig assets to Mobile platform.");
}
public static void UpdateConfigsToPC()
{
string[] guids = AssetDatabase.FindAssets("t:SceneConfig");
foreach (string guid in guids)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
SceneConfig config = AssetDatabase.LoadAssetAtPath<SceneConfig>(path);
if (config != null)
{
config.CurrentPlatform = SceneConfig.Platform.PC_MAC;
EditorUtility.SetDirty(config);
}
}
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
Debug.Log("Updated all SceneConfig assets to PC platform.");
}
private static float buildProgress = 0.0f;
// Method to start the Addressables build and track progress
public static void BuildAddressablesWithProgress()
{
Debug.Log("Starting Addressables Build with Progress...");
// Start the asynchronous Addressables build
EditorApplication.update += TrackAddressablesBuildProgress;
// Trigger Addressables build
AddressableAssetSettings.BuildPlayerContent(out AddressablesPlayerBuildResult result);
if (result == null || !string.IsNullOrEmpty(result.Error))
{
Debug.LogError("Addressables build failed: " + result?.Error);
}
else
{
Debug.Log("Addressables Build Completed Successfully.");
}
// Stop the progress tracking
EditorApplication.update -= TrackAddressablesBuildProgress;
EditorUtility.ClearProgressBar(); // Ensure the progress bar is cleared
}
// Track Addressables build progress (simulated)
private static void TrackAddressablesBuildProgress()
{
// Update progress (this is simulated as Unity doesn't give direct progress for Addressables build)
buildProgress += 0.01f;
// Display the progress bar
EditorUtility.DisplayProgressBar("Building Addressables", $"Progress: {buildProgress * 100:F2}%", buildProgress);
// Simulate a completion of progress
if (buildProgress >= 1.0f)
{
Debug.Log("Addressables Build Progress: 100%");
EditorUtility.ClearProgressBar();
EditorApplication.update -= TrackAddressablesBuildProgress;
}
}
}