Problem with editing a struct that is passed around a lot

Hello all,

i have a complex UMG system,

JCInventory Unreal engine Inventory System by Jack Condon - YouTube seen here,

Im having an issue with modifying the core struct that has all the item data in it.
It will work fine until i close unreal then open it again. I assume this is because of circular dependencys.
I have not used cast to, but have passed a reference to each widget i have created of its parent.
In this way i can work up the chain and get needed information.

Im not sure in what way i am supposed to do this without a widget being able to access data.
I have rebuilt the system from scratch to make sure everything is clean.
but i don’t know good coding practices to deal with this. Its annoying because the system works, but strange things happen reopening unreal (like the struct deletes itself, i assume this is like when a UMG element changes its name to REINST_name and crashes unreal when you click it. The references are replaced but when you open unreal it uses the old references)

Here is a video to be more clear. Any help would be really appreciated! If anyone is unclear please ask any questions.

Hey there,

unfortunately im not able to catch up in your video to provide you with some debugging. It would be really helpful if you
can add pictures of the blueprints you use, which have a relationship to your widget.

I´ve fixed several circular dependencies already and the problems were always quite similar.

Blueprints may be:

  • PlayerController (or the class where you call “Create Widget”)
  • Characterclass (i assume that blueprint to own the InventoryData)
  • HUD-class (if you do something here too)
  • Your Widget

I assume the following:
When you access the Itemdata in your widget, you call something like (GetController or GetCharacter) these are often end up in circular dependencies, you can check that out using the “View References” found in the MenuBar within View. In this View you can check if there are any dependencies looking circular.

What should be done is fully encapsulate your widget from those classes and use EventDispatcher or Interfaces between them instead.

best regards

Thanks there ,
Spent today working on it, got rid of all branch one call loops.
Still could not get the item struct to change without self destruct.
I deleted the system and am going to work on it again.

How do i have an event dispatcher without any references when i need a reference to that object to bind it?

is this true,
I cannot have a widget ever use any information in its parent, is this correct?
So a HUD BP should never access any variables in the player controller controller.
Likewise the HUD widget can never access the HUD BP?

So the character pawn can also never access the player controller?

And the player controller can never access the game mode?

Likewise i have a indivdual wiget that was creating a context menu in its parent by accesing one of its member functions called “Make context window”.
I could not have this, correct? Because the small widget inside the grid can only access itself.

BUT it could have an event dispatcher,
and the Parent could set up binds etc?

is this all correct? i have tried to research this the best i can. After pooring hours a pon hours i really need to understand this concept before i rebuild it.

Thank you so much for your help!

Hey, there.

Well, i would avoid direct references between dependant classes (f.e. widgets and playercontroller). Instead of them i use Interfaces or Event Dispatcher.

“…never access…” of course there is always some dependencies between classes so the answer is: “not directly” OR “it depends on…”.

Im currently working on a tutorial for UMG to show how i do things. But i can provide you with a simple structure picture i made.

But im blubbering around.

Consider this:

This is the structure i work with. But as you can see there are also circular dependencies in there. In order to avoid them, i implemented a third instance which breaks this direct circular dependency.

I consider the PlayerController itself to be the one who handles Input. For me a Character/Pawn/Widget are only bunches of data which reacts to something the PlayerController says or if they are affected by something (OnClickButton in a widget, damagetaking in a character) send a message that the Controller has to do something. F.e. if the character takes damage its health is reduced, and you have a health bar widget which represents your Health, this needs to be updated. Go and tell PlayerController that, so he can update the widget.

My intention was: Do a widget really needs to know about character? No, it only wants to have values to update its content. The playercontroller has references to both widget and character, so he can act like a router, getting the HealthRatio from the Character and send a call event within the Widget to update it.

The HUD do nothing in my case just drawing. If press a key to open a menu, means the input to “open” is handled by PlayerController, he knows the widget and sets the visibility.

I hope this helps you a little bit :wink:
Maybe i will upload the first video today on Youtube.

best regards

however could you provide me with screenshots? i wasnt able to finish my videorecord for the tutorial yet. But i do like to help you with your issues.

Fantastic reply, my system involves a lot of classes working together. im unable to find the specific circular dependency. What im going to do is delete all the UI widgets and start again from scratch. I designed the system in C++ first but because i thought maybe the market place could be interesting i printed it out and moved it over to blueprints, so i still have the C++ working fine.

My current architecture has the player controller spawning an Player inventory actor with all the back end of the system (adding items, getting items data, removing items etc). This reference was passed down to all of the UI elements (dragable window->ItemDisplaysheet(panel to hold next widget->Individual widgets for each item) so that they could effect the Player inventory actor directly by calling its functions.

It is very handy having a reference to the JcInventoryCore.

Here i could pass in the update function the graphics it needs to update with i guess.

Does it work well to use BPinterfaces to pass base classes then cast them when they are needed?
this will create circular dependency in the reference viewer, but is it ok?

Looking forward to your video!

I have removed all my Widgets, all code from my Player controller, HUD and Character, leaving just two classes and one child of one of the classes.
I have check the reference viewer. there is no circular dependencies that i can see. but i made a video to share my viewing.

None of the classes are really talking together as i wanted to isolate the issue as much as possible (nothing is functional, just classes sitting by themselves.

Both the JCInventoryCore and JCInventoryItem use JCItemDataStruct
that is the only thing that is shared. Perhaps this is this issue?
Also the struct has a reference to class JCInventoryItem within it.

The struct still murders itself on load, any advice?
i made one more video. its slow and goes through the refrence veiwer and shows my project very well.

i really appreciate your time trying to explain these concepts to me. I look forward to understanding so i can begin programming the right way.

Ok. Let me try to put it together:

Your PlayerController has:

  • An InventoryCore (some kind of array which saves Items)
  • An InventoryWidget (the visual structure of an inventory)
  • so he has an object Inventory and a reference to the InventoryWidget

Your InventoryItem has:

  • an ItemDataStruct (contains all item information in a container)

You have visible Items (PickUps) in the world, when you pick them up, i assume
you destroy/despawn the PickUp and converts them into an InventoryItem and this will be added to your InventoryCore right?

Your InventoryCore can:

  • Add Items
  • Drop Items

Your InventoryWidget represents the Data inside your InventoryCore.

Workflow: (how i would do it from out of my brain)

PlayerController:

  • Create your InventoryWidget and save its reference.
  • This widget should get a reference to the players Inventory but how?
  • inside PlayerController call a function (f.e. SetInventoryReference) with a reference of your current inventory as a parameter), this means there needs to be a function within your widget called SetInventoryReference and it expects an Inventory reference. So no need to “Get” the reference inside the widget´s logic it receives it from its owner (the player controller).
  • your PickUp Event is called, and the parameter is the iteminformation which will be added to your Inventory
  • after it is added your Widget needs to be updated, another functioncall from PlayerController (f.e. UpdateWidgetContent) fires a custom Event inside the Widget (UpdateWidgetContent) the param is the current Inventory reference and it replaces the reference within the widget.

to be continued…

Now the other way around:

  • you drop an item via drag and drop. The dropped item shall be removed from the inventorystruct. But you have the Up-To-Date Inventoryreference given by the PC, so getting the refvariable and call RemoveItem(droppedItem) should work out just fine.

When writing this i figured there is no need for an interface or eventdispatcher at the moment.

But as soon as you create communications between ParentWidgets and ChildWidgets you will have to use them.

TODO: ill provide you with some example bp´s for the workflow i wrote.

best regards :wink:

Ok here are my Blueprintexamples:

I set up 2 structs (inventory and item, inventory has an itemarray, item just has a Name).

PlayerController has an inventory and a widget. When I create the widget and gets the reference to it, i give it the reference to my inventory using the function SetInventoryRefernce. Now the widget will work with my inventory and all changes it does within its own logic, will affect my inventory directly because i passed it down as Reference. So the widget dont need to get any references by itself.

When i add a new item to my inventory, i call UpdateWidgetContent and give my widget the altered inventory as reference.

When inside the widget the drop action is triggered, means it changes the inventory. Because im working with the reference, i only need to know what Index the dropped item inside the inventory had, and remove that index from the inventory.

To optimize that a bit, i would move the Add Item and Remove Item as functions to the inventory struct. But i lack in time right now :wink:

Maybe this will get you a step closer to what you wanna do.

btw. to explore circular dependencies, you should alter the depth and Breadth within the reference viewer too.

What would a StaffMember say now?

make it a great day :smiley:

I followed all your advice, as well as experimenting here and there. it has been a lot of work to get my head around and a rebuilt the system twice, but i am happy to say its working now without and circular dependency issues. The best part about this horrible process is now i have a much better understanding of architecture so i hope i can avoid or debug these things myself in future. your support and advice has been beyond useful.

Once major change that really effect things was not using anything but native unreal classes in the structs/functions/interfaces and only casting them when i needed them. Because i was trying to make things user friendly i wanted the class drop downs not to be every single actor but just the items you have made, but because the struct is used everywhere it creates bad circular dependency.

This was not my only issue, its so funny because i believed i was being so clean. Hopefully that is the last time i see the mouth of madness (i know it wont be).

Im going to mark this resolved.

problem caused by circular depdencys, help me understand them with good examples.

One major change that really effect things was not using anything but native unreal classes in the structs/functions/interfaces and only casting them when i needed them. Because i was trying to make things user friendly i wanted the class drop downs not to be every single actor but just the items you have made, but because the struct is used everywhere it creates bad circular dependency.

hey there,

im happy to hear that and that i was being of help.

Btw. I finally got my first two videos up on youtube today. They are a bit raw atm because i just created this channel today.

Here is the Playlist Link