UMG Viewmodel

Model-View-ViewModel in Unreal Engine 5.3

Model–View–ViewModel (MVVM) is an architectural pattern in computer software that facilitates the separation of the development of the graphical user interface (GUI; the view)—be it via a markup language or GUI code—from the development of the business logic or back-end logic (the model) such that the view is not dependent upon any specific model platform.

In a prior UE4 project, we had a similar idea called Data Providers, but its implementation was overly complex. Setting it up involved a lot of manual work not only on the UMG side- obtaining and submitting the correct context, requesting the Data Provider, and assigning all necessary delegates, getting the correct values if needed, but also on the C++ side as well.

At first, their main job was just providing data, nothing more. But as we neared the end of development, we saw the need to use some UI elements to call backend logic. So, we switched from using two systems (Subsystems were used to call the backend) to working directly with the Data Providers. This change made the Data Providers able to handle two-way communication.

With UE5, we now have UMG ViewModel:  https://docs.unrealengine.com/5.3/en-US/umg-viewmodel/

As of UE5.3 Viewmodels can be created with Blueprints. 

Before diving deeper, I needed a concise yet illustrative project to showcase the benefits of MVVM without being too time-consuming. I decided to display the game time through different methods: a regular Viewport Widget and a 3D widget in the game world. I quickly prototyped it using Blueprints and later refactored it into C++.

And here are the Blueprints. Notice that the UMG Event Graphs are empty. Also, instead of the timestamp, I am using the float value of GameTime for the red clock.

Ultimately, they’re an upgraded version of UMG’s property bindings, maintaining the same functionality but with significant performance improvements. Instead of constantly checking values every frame, they trigger only when a value changes by default. Plus, there are options to customize their behavior:

  • Immediate: Updates the binding instantly when the source value changes.
  • Delay: Updates the binding at the frame’s end, just before drawing, when the source value changes.
  • Tick: Updates the binding every frame, like a regular binding.
  • Auto: Automatically selects between Immediate and Delayed based on triggers.

I’m only scratching the surface here, but I’m gradually discovering its potential. It’s proving to be quite powerful.