using System.IO;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEngine;
public class BuildReportExample
{
[MenuItem("Example/Build AssetBundle")]
static public void BuildBundles()
{
string buildOutputDirectory = "BuildOutput";
if (!Directory.Exists(buildOutputDirectory))
Directory.CreateDirectory(buildOutputDirectory);
var bundleDefinitions = new AssetBundleBuild[]
{
new AssetBundleBuild()
{
assetBundleName = "MyBundle",
assetNames = new string[] { "Assets/Scenes/SampleScene.unity" }
}
};
BuildPipeline.BuildAssetBundles(
buildOutputDirectory,
bundleDefinitions,
BuildAssetBundleOptions.ForceRebuildAssetBundle,
EditorUserBuildSettings.activeBuildTarget);
BuildReport report = BuildReport.GetLatestReport();
if (report != null)
{
var sb = new StringBuilder();
sb.AppendLine("Build result : " + report.summary.result);
sb.AppendLine("Build size : " + report.summary.totalSize + " bytes");
sb.AppendLine("Build time : " + report.summary.totalTime);
sb.AppendLine("Error summary : " + report.SummarizeErrors());
sb.Append(LogBuildReportSteps(report));
sb.AppendLine(LogBuildMessages(report));
Debug.Log(sb.ToString());
}
else
{
// Certain errors like invalid input can fail the build immediately, with no BuildReport written
Debug.Log("AssetBundle build failed");
}
}
public static string LogBuildReportSteps(BuildReport buildReport)
{
var sb = new StringBuilder();
sb.AppendLine($"Build steps: {buildReport.steps.Length}");
int maxWidth = buildReport.steps.Max(s => s.name.Length + s.depth) + 3;
foreach (var step in buildReport.steps)
{
string rawStepOutput = new string('-', step.depth + 1) + ' ' + step.name;
sb.AppendLine($"{rawStepOutput.PadRight(maxWidth)}: {step.duration:g}");
}
return sb.ToString();
}
public static string LogBuildMessages(BuildReport buildReport)
{
var sb = new StringBuilder();
foreach (var step in buildReport.steps)
{
foreach (var message in step.messages)
// If desired, this logic could ignore any Info or Warning messages to focus on more serious messages
sb.AppendLine($"[{message.type}] {message.content}");
}
string messages = sb.ToString();
if (messages.Length > 0)
return "Messages logged during Build:\n" + messages;
else
return "";
}
}
// For the purpose of demonstration, this callback logs different types of errors and forces a build failure
[BuildCallbackVersion(1)]
class MyTroublesomeBuildCallback : IProcessSceneWithReport
{
public int callbackOrder { get { return 0; } }
public void OnProcessScene(UnityEngine.SceneManagement.Scene scene, BuildReport report)
{
Debug.Log("MyTroublesomeBuildCallback called for " + scene.name);
Debug.LogError("Logging an error");
throw new BuildFailedException("Forcing the build to stop");
}
}