If you ever want or need to display Unity's build report with graphs and charts, you can do that with Power BI. Why do this in the first place? Well, the build report provides a summary of what assets in your game take up the most space. Using Power BI, you will be able see this much easier - analyzing file types and folders in addition to the asset type.
See my updated post here which includes a Power BI template file for download: https://www.antaresanalytics.net/post/unity-build-analysis-updated-version
Source code can be found at the bottom of this post.
1. Save the Unity Build Report
First, you can access Unity's game build report by: Window > General > Console > Open Editor Log (create a build first). You'll then need to save the output somewhere on your computer. For more information on the log, go to https://docs.unity3d.com/Manual/ReducingFilesize.html
2. Connect Power BI to the Report
Open up Power BI and navigate to "Get Data". Since the data is a text file, select the option for Text/CSV. Select your file from the above step. You'll then be presented with a snapshot of the data. Go ahead and select "transform data". Here we will do a bit of data manipulation with Power Query in order to get the juicy parts of the build report.
3. Clean it up First
The first thing you'll notice is that Power BI brought in the data with columns. We chose Text/CSV as our connection method, so any commas that appear in the data will be treated as field separators.
In order to get everything back in one column, I simply created a custom column to concatenate each column with a comma.
I then just removed the other columns to make it look cleaner. Of course, the number of columns will be specific to your build report (because yours may have more or less commas in your file names, etc.).
4. Filter Down to the Build Report
Next we need to remove all of the stuff that appears first in the log. For the purposes of this project, it is not needed. I want to get to the "Build Report", which is about half-way down the log.
4a) Add a custom column which has a logic formula to check if the current line is "Build Report". If it is, then return 1, else return null.
4b) Next we will use Power Query's "Fill Down" function to fill all values that are null will the last value that wasn't null.
5c) Now, we can filter out any null values from the data set. This will return the build report (almost).
5d) Since the build report will always be just those 10 categories, we can simply select the top n rows with the "Remove Rows" function button.
I did this in 2 steps:
Remove the first two rows, since those were just descriptive text.
Then kept the first 10 rows.
Here is what we are left with:
6. Split the Column
Now we need to split the column to separate it into useful fields. Here you can use the "Column by Example" feature for each field you want (there are 3 fields so you would need to perform this 3 times each). You can check out my other post on Column By Example.
7. Convert the size to Kilobytes
Lastly, we just need to convert the file sizes to be the same across the board. I chose to convert everything to kilobytes, but it's up to you. There are a number of ways to do this, but I ended up just creating a custom column with a logic formula.
If the "Size" column = "mb" then multiply by 1000, else return the Bytes.
Other Analysis
You can apply the same steps to get other data from the game build log. I used it to get the assets as well. From there I extracted the file type to show that in a graph as well.
Cheers!
Source Code (Power Query - M)
// This returns the main query called "Editor"
let
Source = Csv.Document(
File.Contents(UnityLogFilePath),
[Delimiter=",", Columns=7, Encoding=1252,
QuoteStyle=QuoteStyle.None]
),
#"Changed Type" = Table.TransformColumnTypes(Source,{
{"Column1", type text},
{"Column2", type text},
{"Column3", type text},
{"Column4", type text},
{"Column5", type text},
{"Column6", type text},
{"Column7", type text}
}),
#"Added Custom1" = Table.AddColumn(#"Changed Type", "Line Text",
each
[Column1]&","&[Column2]&","&[Column3]&","
&[Column4]&","&[Column5]&","&[Column6]&","
&[Column7]
),
#"Removed Other Columns" = Table.SelectColumns(
#"Added Custom1",{"Line Text"}),
#"Added Custom" = Table.AddColumn(
#"Removed Other Columns", "Build Report Check",
each
if Text.Contains(
[Line Text],"Build Report") then 1
else null
),
#"Filled Down" = Table.FillDown(
#"Added Custom",{"Build Report Check"}),
#"Filtered Rows" = Table.SelectRows(#"Filled Down",
each ([Build Report Check] = 1))
in
#"Filtered Rows"
// This part returns the Build Report
let
Source = Editor,
#"Removed Top Rows" = Table.Skip(Source,2),
#"Renamed Columns" = Table.RenameColumns(#"Removed Top Rows",{
{"Line Text", "Build Report"}
}),
#"Kept First Rows" = Table.FirstN(#"Renamed Columns",10),
#"Inserted Text Before Delimiter" = Table.AddColumn(
#"Kept First Rows",
"Asset",
each
Text.BeforeDelimiter([Build Report], " "),
type text
),
#"Added Custom Column" = Table.AddColumn(
#"Inserted Text Before Delimiter",
"Size",
each
let
splitBuildReport = List.Reverse(
Splitter.SplitTextByDelimiter(
" ", QuoteStyle.None
)
([Build Report])
)
in splitBuildReport{3}?,
type number
),
#"Added Custom Column1" = Table.AddColumn(
#"Added Custom Column",
"Bytes",
each
let
splitBuildReport =
Splitter.SplitTextByDelimiter(
" ",
QuoteStyle.None
)
([Build Report])
in Text.End(splitBuildReport{0}?, 2),
type text
),
#"Added Custom" = Table.AddColumn(
#"Added Custom Column1",
"Kilobytes",
each
if [Bytes]="mb" then Number.From([Size]) * 1000
else Number.From([Size]),
type number
),
#"Removed Other Columns" = Table.SelectColumns(
#"Added Custom",
{"Asset", "Kilobytes"}
)
in
#"Removed Other Columns"