[4.6] Breaking UMGs with circular references

My project that worked fine in 4.5.1 is unusable in 4.6 since any UMG widget which contains a circular reference gets polluted with REINST versions of it’s user widgets.

Steps:

  • Create a UserWidget called “ChildWidget” (add an image or text to it so you can see it)
  • Create a UserWidget called “ParentWidget” and add an instance of “ChildWidget” to it in the UMG editor
  • Create a GameState-derived class called “MyGameState”. Make it the project’s gamestate in the project settings.
  • Add a BeginPlay event to “MyGameState”, where you create an instance of the “ParentWidget” and add it to the viewport
  • In ChildWidget’s graph, add a Construct event, call GetGameState() and cast the returned GameState to MyGameState.
  • Save your project, close the editor
  • Reopen the project
  • Open ParentWidget layout editor. The “ChildWidget” instance will be replaced by a “REINST ChildWidget C” instance. If you had any interaction with ChildWidget in the ParentWidget graph (like calling a method on ChildWidget), the links will be broken.
  • Deleting the “REINST ChildWidget” and adding a “ChildWidget” will give you an error when saving (you can save if you try again).

Hello ,

I followed the instructions in your post and was unable to reproduce your issue. I have a few questions for you that will help narrow down the issue that you are experiencing.

Quick questions:

  1. Can you reproduce this in a clean project?
  2. Can you provide screen shots of the blueprints that you are using?
  3. Could you provide more information on what it is that you are trying to do?

Yes, I can reproduce it in a clean project. Here are screenshots of each step:

The assets:

23061-assets.jpg

Setting up the Game Mode and Game State in the project settings:

23062-projectsettings.jpg

MyGameState graph (references ParentWidget):

ClientWidget graph (references MyGameState):

(Continues in next commend due to attachment limit)

(continuing)

Now add a ClientWidget instance to ParentWidget in the UMG editor:

23065-parentwidgettree.jpg

Make a reference to ClientWidget in the ParentWidget graph:

23066-parentwidgetgraph.jpg

Save everything, close the editor and re-open the project. This is what happens to ParentWidget:

23067-parentwidgettreeafterreload.jpg

My project uses lots and lots of user-created widgets and many of them reference my Blueprint GameState class via a cast to call events and bind to dispatchers, while my own GameState needs to reference some UserWidget classes to add them to the screen when some things happen.

For example, when the game starts the GameState adds a LevelSelectWidget to the viewport. Selecting a level on the UMG widget calls a function on the GameState that does some bookkeeping and loads the level.

I don’t think I’m doing anything arcane, unless I’m the only person using UMG and placing UserWidgets inside other UserWidgets (which I find it hard to believe) and doing basic blueprint communication (maybe people add all their logic directly into their Widgets and don’t practice any code reuse?).

Re-working my project to avoid the circular reference would require me to place all functions I use on my GameState behind an interface (and remove the casts) and move the event dispatchers to another singleton that references nothing else, but it doesn’t guarantee I won’t run into it again, because I just tested and the problem happens no matter how deep the circular reference is (so if my UserWidget I reference a class that references another class, that references another class that references another UserWidget that contains an instance of the first UserWidget, things still break).

Hello ,

First off, thank you very much for your detailed reproduction steps. That helped out immensely. I have written up a report ( UE-6316) that I have sent to the developers for further review. The Engine is working as intended, however I submitted a request to examine the error messages that are supplied when working with circular logic. I will provide updates with any pertinent information as it becomes available.

Make it a great day

Thanks! I’ll roll with 4.5.1 for the moment (man, I was looking forward to pure casts).

Glad to see they are fixing this :slight_smile:

I put together a tutorial on how to work around cyclical dependency issues in UMG here: link text

Avoiding circular references is not a good solution, specially when they work perfectly well in 4.5 but broke in 4.6 for some reason.

Also, creating an interface for every single little function slows down development quite a bit, since context-sensitiveness is lost: I have to dig the blueprint popup for the functions I want to call from a list of all interface functions.

At the very least, if Epic indeed wants to disallow circular references going forward they should make it the engine detect them properly at the moment they are made instead of stealthily messing up the project the next time it’s loaded and possibly destroying hours of work (since the circular references do work while the editor is open). The current behavior definitely shouldn’t be “the way the engine is supposed to work”.

Hello ,

I may not have been clear in my answer. What I meant was that the report that I filled out was to increase the users awareness of circular dependencies and to provide more accurate and helpful error messages to let them know when and where the issue occurs.

Hi Rudy,

I appreciate the answer. Seems I’ll have to find my a way to break my UMG-related circular references then? Oh well, I’ll try to figure out the less painful way to do it, probably an object hidden behind an interface that keeps the references to my widget classes and return them by name or something.

I still want to voice that I think something is amiss there, because non-UMG circular references don’t seem to cause any problems. If those end up being disallowed as well, the interface system will need one hell of an usability revamp because pretty much every sort of “central” classes like gameInstance, gameState, singletons, HUD and etc will need to be hidden behind interfaces.

Hi Rudy,

I somehow got the bug to trigger in 4.5.1 too. I think I stumbled upon the feather that broke the camel’s back involving some TSubclassOf<> properties, so it seems I have to clear up all circular references involving UMGs after all.

Currently it’s very time consuming to move existing functions to interfaces, since the editor will scream in protest if you have functions with the same names as the interface ones (if only it would detect them and simply convert them to implementations automatically… wink wink).

I was looking into ways to keep class references without creating circular dependencies and it seems that using TAssetSubclassOf<> instead of TSubclassOf<> and manually loading the classes before use seems to work well so far. I’ll come up with a way to remove the direct references to my widgets from my BPs and replace them by TAssetSubclassOf<> somehow (it’s a shame we can’t make BP-only lazy references).

Updating: while TAssetSubclassOf<> fixed my problems in 4.5.1, it seems 4.6.1 hates it. Crashes, crashes and more crashes. Even closing the editor without doing nothing will crash on me. “Invalid object in GC” on a call to an interface function. If I remove that node, the crashes moves elsewhere and then on and on and on. I’m at my wits end here. Seriously considering scrapping 6 months of work and moving to Unity or something. I can’t believe I’m the only one having so many issues. Maybe everyone do everything in C++ and Slate and barely use Blueprints at all?

I have the same issue (appeared today) and lots of crashes too, with pure blueprint project. Very annoying, now i’m stuck with my project because of this REINST errors in my main UMG widget. I’m also interested about what’s the progress of fixing this bug.

It seems using lots of blueprint in my project was a mistake, because there’s little guarantee things will continue working in future versions and once UE4 decides it doesn’t like your Blueprint you’re SOL and all work put on it is lost.

One of the many different crashes I’m getting in 4.6.1 was caused by a few NULL nodes in a blueprint graph, which means some nodes got “eaten” during loading for some reason.

If I make another UE4 project, I’ll be sticking with C++ for as much as I can possibly manage.

,

The crashes you are mentioning do not appear to be directly related to the original issue in ways other than the fact that it was an attempt at a workaround. That being said if you like to post another question on the AnswerHub specific to the crashes you are experiencing, this will allow us to assign a more specific engineer. After this we will be more than happy to assist you further.

Make it a great day

Yes, I realize this now from reading other bug reports. I’m seeing at least two distinct crashes that were reported elsewhere, one caused by the blueprint compiler modifying property offsets multiple times due to blueprint circular references and causing them to point into invalid memory addresses and another caused by a bug involving event dispatchers used in classes that are loaded during engine startup (gameinstance, gamestate and HUD). I’ll monitor those posts for solutions.

You don’t want to fix this? Cyclical dependency works in c++ so it should also work in blueprint/UMG. I have this error in one of my UMG menus and the only solution I found is just to recreate the child widget every time after opening the editor, since moving the stuff into interfaces is way too much work.

Hello ,

At the time that this post was originally made that was the current standing. However, since then the developers have been working to make improvements to how the engine handles circular dependency issues.