top of page

LOD Analysis Tool Blog - Complete

  • Writer: Jesse Olchawa
    Jesse Olchawa
  • 1 day ago
  • 20 min read

Date: 08/04/2025



Quick Intro:

As its easter break I decided to use the time prior to university starting up again to brush up on my Python knowledge. I have not used Python in some time and have especially neglected using it in my Unreal Engine tools. I want this project to finally beat my addiction to shiny, colorful node networks and divde into the more organised scripting dimension of making tools.


Brief:

I will be following a industry brief that details creating a tool over 4 weeks. I will plan my time as following:


Potential Problems:

Ontop of being heavily rusty with Python and have not used the Python API with Unreal Engine 5, I have a 9-5 for the weekdays. This will affect my available hours so I will be using my weekends to push for completing this brief. Furthermore the university term starts up again on the 28th so that will take out my final Monday entirely, I need to ensure I am fully done with the project well prior to this.


Brief Essentials:

I need to ensure I meet the following requirements:

  • report basic info to user - name, bounding box, tricount, number of materials for each lod, vertex density (number of vertices divided by bounding diameter), number of small triangles (area below 1cm), thin triangles (angle smaller than 15 degrees)

  • have a working user interface for running and presenting results

  • have a method to run across multiple assets - exporting data to csv file

  • document functionality of the tool in user guide


Some stretchgoals I would like to hit are:

  • evaluation collision

  • excel functionality to bring across problem assets by filtering or formatting

  • written entirely in python or maxscript (maybe one of each)

  • have a video presentation of tool and talkthrough

  • identify number of meshes in scene ~ estimate tricount from here

  • showcase savings from LODS by calculating against original tricount


Sign Off:

I am quite excited to begin this project and can't wait to learn more about what Python has to offer with Unreal Engines blueprints! Stay tuned


 

Date: 09/04/2025

Planning and Setup:

To begin my project I setup Visual Studio Code with Nils Sodermans useful editor based plugin. I followed the following two tutorials to help set this up correctly.


(MattLakeTA, 2022)
(Teucher, 2023)

Flowchart of Logic:



Here is a flowchart showcasing a high level overview of input and how that leads to data being gathered. I have also outlined what variables I will need to process to help meet the brief and make the tool more useful to use. I want to have one big master button that gathers this data and another to export to keep it simple. I can add more buttons to help tweak the data too for adjusting screensizes, mesh selected and more however it would still follow this graph.


Bibliography:

Teucher, D. (2023)  Unreal engine 5 tutorial on running python inside visual studio code to streamline game pipelines, YouTube. Available at: https://youtu.be/bGduLTUIWFY?si=lhBh4-EEPfhmQ4xt (Accessed: 09 April 2025).

MattLakeTA (2022)  Run Python In Blueprints Utilities - Build Editor Tools! Unreal Engine 5 Tutorial , YouTube. Available at: https://youtu.be/JP_EOAGS634?si=GcYFVrWt3v45pnhh (Accessed: 09 April 2025).


 

Date: 11/04/2025

Problems:

Unfortunately I am quite busier with work than anticipated so I have had less time than ideal to work on the tool. However this is not my core problem as I have had issues with gathering selection with my current Python script. As seen below selection needs to dictate if meshes are being selected in level or editor. I have resolved this with a boolean called Artist Mode. I plan to have this boolean take data from a checkbox or dropdown widget element however for now I need to manually encode what it will do. Furthermore this script does not loop per asset, meaning I cannot export data out. I will need to loop this function per each select item in array to fix this. However the script gathers all my necessary variables in a very crude print line. So paste it into your Editor if you'd like to check it out!

Current State of Code

Improvements to Apply:

As spoken about earlier the script does not loop per selected asset. This is a easy fix that I plan to go through each array item with a counter and export this data in some form. My greatest hurdle is the .csv format as I have never worked with writing to .CSV before so I do not know how I should package my data from selection to be read. I assume it will most likely be string, so I may need to make a large string or string array to collection each selection. However I will need to do more research into this before I test it out.


Furthmore a critical bug I have had is inconsistency with the collision detection. No matter what I change in the static mesh editor, meshes in any mode refuse to display correct collision enabled or disabled. The type is easily obtained but I am at a loss at what is wrong especially since the in engine collision viewmode is displaying correctly? So it must be something to do with Python. I will do my best to resolve this however in the essence of time I may leave this till the end as it is not tool breaking.


Issue shown below:


Collision viewport working however the tool disregards this
Collision viewport working however the tool disregards this


UI Designing:

Since I have figured out what data I moved onto designing a UI, for inspiration I looked to Nina Klos's most recent tool project.

What I loved most about it is how clean and easy to read the setup is alongside being docked nicely in the left corner of the viewport. The thumbnail also made it easy to tell which asset was inspected which I never knew you could do before, super awesome work. So I took a screenshot of my own viewport and began to draft a concept layout below.


LOD Tool UI Draft 1.0
LOD Tool UI Draft 1.0

There was a lot of variables I would need to display so to makeit easier I plan to have the categories become collapsable or scrollable as I have done with widgets in the past. I ranked the parameters by what is needed most, making the name, location, tricounts, scale etc appear at the top. Then further down more LOD settings would appear ending with the CSV export button. I did not want to incite accidental export presses by grouping a ton of buttons at the top together so by leaving this button last you would really need to commit to the scroll to export out that spreadsheet! Making this menu has also made me realise theres more data I want to include such as instances in scene by counting.


You may notice a material section which I am on the fence about including as this a focused LOD tool so info on materials may make the scroll longer. I will need to test this further. I also sought some feedback from my peers and they advised that I would need better grouping and buttons included as its quite the info dump at the moment which I will get to when I implement it for real using Unreals Vertical and Horizontal boxes.


Sign Off:

Tomorrow I plan to jump onto inserting my script into a widget instead of my remote execution and put my UI design to the test. I'm excited as UI is a element I quite enjoy as it feels like sorting pieces of a puzzle together.


Bibliography:

Blueprint Utility Widget - Unreal Workflow Tool, Nina Klos 🐟 (2025) ArtStation. Available at: https://www.artstation.com/artwork/JrJGv0 (Accessed: 11 April 2025).


 

Date: 13/04/2025

Intro to CSV:

I do not have a lot of time today so I will be exploring csv scripting to get that deliverable met. I found a super useful post from 2023 by Damilola Oladele titled "How to Create a CSV File Using Python" (Damilola Oladele, 2024) which is exactly to the letter of what I need. It was suprisingly straightforward and it made me realise the true power of Python, you just import a library to fit whatever you need.


To test it out I rewrote the example script with the data I would need in a header and hit run in the Python terminal. It did not work and I realise that the terminal was not pointing in the correct locaton to send this csv and so I ran it again and behold!

IT WORKS!! CSV EXPORTED
IT WORKS!! CSV EXPORTED

As a avid lover of spreadsheets (I even have a enamel pin of Excel thank you Craig!) this literally blew my mind. So many options expanded before me and I know I want to do so much more with this type of script. However it is not complete yet, my largest issue at the moment is that the file path is my default location on C: so it has to be manually moved every run. I can however see a solution by either inputting the directory through paste when prompted or some sort of library that can look through file validation. Either way theres still some polish for this left and then further testing with actual string data that has been pushed through.


Heres the code:

State of CSV Code



Bibliography:

freeCodeCamp.org. (2023). How to Create a CSV File Using Python. [online] Available at: https://www.freecodecamp.org/news/how-to-create-a-csv-file-in-python/. (Accessed: 13 April 2025)

 

Date: 15/04/2025

UI Development:

So I have worked hard on getting the UI up and running. Its quite responsive and has a good amount of adjustable buttons and dropdowns to help get more insight on selected assets.


UI in Runtime
UI in Runtime

UI Breakdown
UI Breakdown

I have adjusted the scrollbox for the screenshot however everything composes neatly into a master vertical box filled with category vertical boxes. To ensure that parameters display well spaced there are several horizontal boxes used to layout data. As mentioned before its quite the overload at the moment so I have worked hard to get collapsable menus working.


Collapsable Menus:

As there are a lot of menus I want to collapse I knew I wanted to create a function that could reuse the logic of plugging in a section (vertical box), check if its visible and do the reverse of its state. I'm uncertain if this is a bit of a cheat however when looking on the Python api for components I have not talked to before such as the widget tools I try visualise what I need by drafting the logic using Blueprinting.

Logic in Blueprint
Logic in Blueprint

I then write it out in Python script instead which ends up being a lot more compact than so many several nodes.


Logic in Python
Logic in Python

I then created a input for the input variable (vertical box) to plugin.

Python Script for Collapsable Menus

import unreal

if categorytocollap.visibility.value !=1:

    categorytocollap.set_visibility(unreal.SlateVisibility.COLLAPSED)

else:

    categorytocollap.set_visibility(unreal.SlateVisibility.VISIBLE)

My event graph now is clean ad short, looking like this:


On Pressed to Hide Function
On Pressed to Hide Function

And the grand finale, behold it working in engine!


Menu Hide Working in Realtime
Menu Hide Working in Realtime

Thumbnail and Level Dropdown Execution:

So to start off I knew I needed a way to isolate if the user is selecting in Level or Content Browser as it basically makes or breaks the way select static mesh needs to respond ie cleaning up the selection for only static meshes or prevent selecting non static meshes. I tested out a bit of isolated code to see if I can get a input dropdown index value and use that in if else statements.


Furthermore I wanted visual confirmation that yes I did select the asset it was telling me I selected so this would be done in the way of sending this asset data to the thumbnail. Here is my codes:


Dropdown Selection in Python

Getting Thumbnail Content Browser

And heres how it runs in combination with my other script.


So I have a slew of a few issues with gathering thumbnails in level I suspect this may be due to it needing to dig deeper to call the asset data value. However the remainder of the script runs well! And it prints all the info the output log. This is not ideal, I do want it to project it onto the UI so that would be my next step by hooking up a ton of inputs like I did for my hide python function.


Progress of Code


 

Date: 18.04.2025

Setting UI Values Works!

I jumped out of my seat when this finally worked as the amount of time fiddling with inputs felt like forever to ensure all the values were set correctly. However I'm happy to report all printed data is now set in a clean manner up on the widget itself. Heres a video:


Data Set on UI from Python

Heres how the spaghetti looks under the hood:


So much blue its a ocean of spaghetti
So much blue its a ocean of spaghetti

Whilst it does not look pretty it certainly works! I know one big future aspect I want to work on is my naming conventions, it ended up causing so many issues mispelling, figuring out if I was talking to the the text component or string however for the sake of time it is what it is.


Progress of Code - Its really long now be warned


Fixing Missing Thumbnail on Start:

One issue I had was the tool had no thumbnail to select at the start of construction. I ended up going with the most foolproof option of selecting a engine cube since that asset always exists. Heres how it looks plus the code:


Empty to Default Cube Thumbnail on Construct
Empty to Default Cube Thumbnail on Construct

How code is plugged in
How code is plugged in

Code for Default Cube


Reflection

I am running quite behind on my tool at the moment, according to my schedule I should be on documentation. However I need to still tackle the following things:

  • CSV Export from selected data

  • Folder location input somehow

  • Lot of missing functionality from buttons like update screen size or selected item dropdown

  • Some of the default text is weird like verts on tris etc needs updating


Sign Off:

For the essence of time I will be focusing on functionality and the core aspects such as the exporting. I may need to cut some options such as the dropdown index selection or adjustments however they can always be added later, its time to focus on the fundamentals features.


 

20-23.04.2025

So much work, so little time

I decided to really focus over the past few days to update, fix and get elements functional heres all the work.


Rewrite for Clean Looping

I decided to export the data across to my CSV it should be ammended into a string array. My initial approach was a bit nightmareish, I decided to just copy and paste my code, removing the set data and cleaning it up to focus on a good string export. This ended up predictably, doubling my line count to 475 lines.


Not good, time to rewrite
Not good, time to rewrite

So my rewritten and final code looks like this (and is only 275 lines!)


Progress Code

Code is refusing to pase to WIX so here it is uploaded to pastecode instead: https://pastecode.io/s/735yzamj

UI Update

I got some feedback from my peers that the UI is quite barebones at the minute and could do with some splashes of color to distinguish core buttons. The menus being hideable were also not clear at all and a lot of data was centred which looked off. So I went to work quickly redesigning it and implementing a refresh.


Photoshop Edit
Photoshop Edit

In Engine Preview:

Engine Preview New UI Revamp

I quite like how the borders split up data and after showcasing it back to my peers they have mixed opinions. On one hand some of them like the colors and some of them dislike the amount so I may simplify this to shades in the future. However the borders have been a brillaint success alongside my written tooltips explaining a bit more of how elements are calculated.


Exporting Data from Selected String using Categories

I figured out via counting that my total string array would be 17 entries per row, so using this figure I could divide a total length of a array to figure out how many lines to write.


If the array is for example 34 in length this means there are two rows or two different selected objects to write.


From this I could also isolate not to write a row if not selected in the checklist via the popping command.


Screenshot of me counting and removing unused string headers


I ended up encountering some problems initially as I made it only count to 16 which ended up cutting off the material count as I mistook the value 0 for not counted.


Here it is finally working!

Exporting all, none or select categories to .CSV

Code below for you to try, hook it up to UI element to check from in inputs alongside a string array to go into it.

Export CSV Code


Folder Selection:

I knew I wanted the user to choose the folder to export to so I did some research and found a brilliant library called Tkinter (geeksforgeeks, 2020). From the post I would not need the button as I would be calling it via the on pressed button in Unreal however the remainder of the code would be highly relevant in getting the file path. Heres how it works:


Folder Select Window
Folder Select Window

Blueprint Overview:

Connection to CSV Export Script via String
Connection to CSV Export Script via String

Code for Folder Select



Sign Off:

This all for production, I will just need to write up my documentation and my project is finally finished!



Bibliography:

geeksforgeeks (2020). File Explorer in Python using Tkinter. [online] GeeksforGeeks. Available at: https://www.geeksforgeeks.org/file-explorer-in-python-using-tkinter/ [Accessed 23 Apr. 2025].



 

24.04.2025

Writing Documentation

As I have never written documentation before this came to be quite the challenging task. I knew what I wanted to state however I knew I would need to brainstorm everything that would be important for using the tool for the first time plus problems that might appear. When designing this documentation I used peer feedback to help strengthen the topics covered which came in quite handy.



Sample of my LOD page before adding images
Sample of my LOD page before adding images


I initially wrote everything without pictures to try and put in words as much as possible before adding the pictures as a bonus ontop. I kept functions basic and explanations to the point.


Heres the final result with a fancy cover too! Download it below!


Cover for my documentation
Cover for my documentation


For my cover I used the tool in a sample environment by Quixel Megascans to help get a taste of what it would look like in a full game scene! Its a brilliant and tasty medieveal banquet do check them out below.


Bibliography:

Fab (2024) Medieval Banquet, Fab.com. Available at: https://www.fab.com/listings/d422ac6c-ce50-4273-8d4a-2ac594a3a2b2 (Accessed: 24 April 2025).



 

25.04.2025

Project Renders

Heres some breakdowns of my blueprint setup and final video showcase of features. As everything is primarily running through scripts my previous days post may be better to preview those elements.


Full Video Function Showcase:

Full Video Overview

Breakdown Shots:

Blueprint Overview
Blueprint Overview

Main LOD Script
Main LOD Script

Folder Selecting
Folder Selecting

Collapsible Menus
Collapsible Menus

Pre Constructon and Link Script
Pre Constructon and Link Script

User Interface
User Interface


(Update From Future Me) I have also cross posted this to Artstation with a link to here blog!






Project Post Mortem:

What Went Well:

Overall I'm quite happy with the tools output and result. Whilst there may be a few bugs with collision remaining the usability is still consistent and simple to pick up. I've had positive feedback overall and I have learnt quite a lot about python I have not known before. I also feel they this tool is a brilliant template for other widgets I can create that need to utilise UI elements such as a material swapper or mass renamer. I have also been able to implement functions, loops and cut down my code to be quite optimised over the course of my development.


What Went Wrong:

As it's my first major python tool I have had numerous issues with elements running, looping, bad syntaxes and missing parameter values near the beginning. However, I have been able to learn from my mistakes and become a lot faster at debugging. On the other hand, the tool is still limited from what I wanted it to achieve in the scope of in engine usability. This includes a drop-down menu to select the assets, ability to adjust screen space or material values on the select asset too. Due to time which again has been another aspect that went quite poorly due to my fulltime job commitments I have had to cut quite a bit. At the end the project still meets what is required for the brief but in the future, I want to add to it, to make it even better than it was before. I also need to break a bad habit pointed out to me by a peer who codes that is my disastrous parameter naming conventions. I had a lot of problems with missing variables due to me not painting the same names through my inputs so in the future I want to break my bad habits and commit to a clearer naming scheme. This would include where it is so if a text element is in the UI it would be UI_Mesh_Name and the input in Python would be Input_UI_Mesh_Name. My only fear would be very long string names so I may also simplify it to what it is for clearer reading such a s vb_Lod_Stats for vertical box lod stats for example. It is quite too late to rewrite now as it would break all my code


Final reflection:

In conclusion I would consider this a semi successful project in meeting the brief but leaves enough wiggle room for future upgrades. It was also my first time writing proper documentation which I want to do more of as it was both super fun and super helpful when passing for peer feedback. For my future projects I want to make a few more of these tools using purely python and head into Houdini to bridge the gap into more 3D based procedural tools.


Comments


© 2025 Jesse Olchawa

The content provided on this website cannot be utilised for any AI training or data gathering purposes!

bottom of page