x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

[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).

Product Version: Not Selected
Tags:
more ▼

asked Dec 04 '14 at 09:40 PM in Bug Reports

avatar image

pedro_clericuzzi
303 20 24 155

avatar image Rudy Q ♦♦ STAFF Dec 04 '14 at 10:31 PM

Hello pedro_clericuzzi,

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?

avatar image pedro_clericuzzi Dec 05 '14 at 12:41 PM

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

The assets:

alt text

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

alt text

MyGameState graph (references ParentWidget):

alt text

ClientWidget graph (references MyGameState):

alt text

(Continues in next commend due to attachment limit)

assets.jpg (16.9 kB)
mygamestate.jpg (48.4 kB)
clientwidget.jpg (53.5 kB)
avatar image pedro_clericuzzi Dec 05 '14 at 12:44 PM

(continuing)

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

alt text

Make a reference to ClientWidget in the ParentWidget graph:

alt text

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

alt textalt text

avatar image pedro_clericuzzi Dec 05 '14 at 01:02 PM

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).

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

1 answer: sort voted first

Hello pedro_clericuzzi,

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

more ▼

answered Dec 05 '14 at 03:48 PM

avatar image

Rudy Q ♦♦ STAFF
47.4k 545 132 525

avatar image pedro_clericuzzi Dec 05 '14 at 06:58 PM

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

avatar image BaronPumpky Dec 09 '14 at 04:40 PM

Glad to see they are fixing this :)

avatar image Jared Therriault Dec 19 '14 at 04:09 PM

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

avatar image pedro_clericuzzi Dec 22 '14 at 06:35 PM

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".

avatar image Rudy Q ♦♦ STAFF Dec 22 '14 at 08:03 PM

Hello pedro_clericuzzi,

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.

avatar image pedro_clericuzzi Dec 22 '14 at 09:14 PM

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.

avatar image pedro_clericuzzi Dec 29 '14 at 04:17 PM

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).

avatar image pedro_clericuzzi Jan 05 '15 at 09:12 PM

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?

avatar image John Alcatraz Apr 01 '15 at 04:22 PM

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.

avatar image Rudy Q ♦♦ STAFF Apr 01 '15 at 09:09 PM

Hello John Alcatraz,

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.

avatar image John Alcatraz Apr 01 '15 at 10:02 PM

ok, so this means you will fix the bug? It's still in 4.7.4.

avatar image John Alcatraz Apr 02 '15 at 04:02 PM

Will you fix it or will you not fix it?

avatar image Rudy Q ♦♦ STAFF Apr 02 '15 at 05:15 PM

Hello John Alcatraz,

To be more clear, I looked over the status of the issue and it has been changed to resolved internally and this solution should be available in a later release of the engine. I hope this answers your question.

avatar image John Alcatraz Apr 02 '15 at 06:08 PM

Yes, it answers my question :) Could you also tell me whether there is the possibility for this to be included in something like a 4.7.5 hotfix? And if not, will a "later release" be 4.8?

avatar image Rudy Q ♦♦ STAFF Apr 02 '15 at 06:29 PM

Hello John Alcatraz,

There is no exact time frame in place for the implementation of this solution.

avatar image John Alcatraz Apr 03 '15 at 11:40 PM

If you can't tell when ths will be fixed, is there something like a workaround for this?

I am using the widget A as my main UMG widget which is drawn in the viewport. This widget B inside of widget A uses the "Get Owning Player Pawn" function and casts the Player to my own Player. My Player of course references it's Player Controller, and in the Player Controller I have a reference to widget A since this is the place where I add the widget A to the viewport.

avatar image pedro_clericuzzi Apr 05 '15 at 09:48 PM

I'm still on 4.5.1 which is less picky about circular references involving UMG, but I've been gradually refactoring my blueprints to get rid of circular dependencies before trying to upgrade to a newer version, so I can give you some advice about it.

First thing is that most cases of circular dependencies are born from code that is too tightly coupled. While I agree UE4 should not break under tightly coupled code and I'm glad they are working on it, your project (and sanity) can only benefit from loosely coupled code design. It makes it much easier to plug/unplug things and makes it easier to reuse blueprints across different projects.

Event dispatchers are a great way of decoupling your blueprints without the need for laboriously wrapping everything behind interfaces. They also have the bonus of making it very easy to add functionality without bloating your blueprints.

You can use a shared actor/object that contains the event dispatchers and can be accessed by your other classes. It's crucial that the dispatcher class doesn't have references to any other of your classes, so it doesn't depend on any class other than itself. This includes event dispatcher parameter types.

In your case, instead of having your PlayerController class create the WidgetA, you have it call a dispatcher on the "SharedDispatcher" informing that the playerController has been spawned (or whatever event it is that needs WidgetA to be displayed).

Now, you need to move the WidgetA spawning code to somewhere else. This needs to be a blueprint that is guaranteed to not cause a circular reference. The best options are either your level blueprint or an Actor-derived class that is placed on your level. There you bind a custom event to the SharedDispatcher "PlayerControlledSpawned" dispatcher, which creates WidgetA and adds it to the viewport. Since none of your custom classes will reference this blueprint, you're free to do other tasks here with zero risk of circular dependencies.

avatar image Slavq Jan 05 '15 at 11:26 PM

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.

avatar image pedro_clericuzzi Jan 06 '15 at 01:23 AM

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.

avatar image Rudy Q ♦♦ STAFF Jan 07 '15 at 08:47 PM

pedro_clericuzzi,

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

avatar image pedro_clericuzzi Jan 09 '15 at 03:11 PM

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.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question