I have a number of widgets than contain the same set of variables. In a blueprint, I select which one of these is going to be created. However, the ‘SET’ node has to target a specific widget in order to reference a variable in that widget to set.
I know, irrespective of which widget is selected, that these variables are present, so can I set it up so that I can set the variables regardless of which specific widget class they’re in?
Hopefully, the screenshot below will help. When I hover over the target input pin of one of the SET nodes, it specifies that the target is a specific widget. This means that if I set the Class input pin of the create actor node to anything other than that particular widget (which will be done programmatically) I can’t set those variables.
I’m trying to avoid having ten copies of this code to cater for all the possible widgets that could be created.
Since I can’t see the part of the blueprint where you’re determining the class, I can’t tell if you’re casting to the class to see which kind of widget you’re getting, but I would suggest that if you aren’t.
As far as setting the variables go, if all of the classes have the same variables, it may be best if they were children of a parent blueprint that contains all of these values instead. This way, no matter which one of your widget classes it ends up being, they’ll always end up being the same variable type. You should be able to reparent your blueprints but it may take some reorganizing, depending on what you have set up so far. For some documentation on blueprint inheritance, please take a look here.
The idea is that you’ll create a “Widget_Base” class and then have all of these Widget classes inherit from it (have it set as their parent BP.) You’ll then create the variables that all of them share inside of Widget_Base and they’ll inherit those variables.
Apologies for missing off the part where I determine the class - it wasn’t working properly so I moved it out of the way. However, the class output by that part will one of several objects of the UserWidget class.
I originally thought about using children but couldn’t figure out how to do it. Prompted by your suggestion though, I’ve spent a bit more time on it and now I’ve made a few of the possible user widgets children of a base UserWidget. I can get the basic method to work but, unfortunately, when you make a child widget (by selecting my base widget in the ‘pick parent class’ menu in the content browser) the new child widget comes up empty.
Although it inherits the parent widget’s functionality, this means I cannot make the changes (image dimensions and animation key values) for which I had multiple copies in the first place.
By the way, you were right to ask if I was casting. I didn’t need to do that when I was explicitly creating each type of widget but it’s what was missing when I tried the parent/children method. I really need to get into the habit of thinking about casting!
In reference to the last part of your comment, does that mean you were able to get it working? As far as setting an existing blueprint’s parent class, you would want to do that from the Class Settings window in the blueprint that you wish to be the child and then select the base. It shouldn’t be creating a new child widget, it should just be changing the parent of your existing one.
I did get it working, yes. However, it’s only worth it with the child that is identical to the parent as I can’t modify the children. If I make a copy of the base widget and use the class settings to set the parent class I’m then faced with a raft of duplicate variable errors (which includes the animation). If I create a new widget and set that to my parent class I need to construct everything inside it which is more work than just duplicating the base class and modifying the bits that need modifying.
Fundamentally, the problem seems to lay with the fact that making child UserWidgets doesn’t work the same way as making child Actor blueprints.
I’ve actually spent more time figuring out a way to avoid creating ten versions of the bit of the BP script I showed in my image than if I’d just done that and left it! I’m sure anyone with programming experience can relate to my frustration that I can’t find a more elegant solution though.
Right now, I just need to get it working. If a more elegant solution reveals itself that would be good but it isn’t a blocker to getting the functionality required (the player will never know the difference!).
If it’s working for you and that’s alright for now, I’ll be marking this as resolved. If I can come up with a more efficient solution, I’ll be sure to let you know but I would need to spend some time experimenting to see if I can get it working, since you’re saying that it’s working differently for widgets as opposed to blueprints.
This problem has reared its ugly head again as a result of this bug: [UE-4659] (which was logged over two years ago by the way).
The reason I needed to have a single parent widget and multiple child widgets is because each child needs to be a different size (as they are items in a Deus Ex: HR-style grid space inventory), but I only want to have to reference the parent via a cast in order to set the variables (the way I do with actor children).
The only way to make it work was to do what I mentioned in my original post, i.e. make a copy for each possible size. This results in this hideous mess (plus another, similar-looking one where I’m doing something else to the inventory items):
What this is doing is getting the dimensions of the actual item (from the actor BP) and choosing which inventory widget to create, then setting all its variables and its location in the inventory. This is because it’s not possible to do it generically as I illustrated in the image in my OP.
However, UE-4659 now causes problems because the inventory items need to be rotated. The only way I can see around it is to painstakingly create new versions of every widget in which the X and Y dimensions are swapped, and then tediously create more of the tangled mess above.
I just want to be able to have a 1x1 ‘master’ widget, so that I can create a child of it, open that child and change its size and animation properties so that it’s, say, a 3x2 version of the master. Then I can just cast to the ‘master’ in order to set the variables. Setting a widget’s parent in the way you describe results in the errors seen in the following image, which makes that impossible.
When you go to reparent the blueprint in the way that I showed, does the child already have some of the variables that you want it to inherit from the parent? That could cause these messages to appear. If not, could you give me a screenshot of the complete variable list for your parent and child blueprints that exhibit this issue?
Have you looked into using an interface blueprint? I found it’s an easy way to communicate the same data to different classes of blueprints. You can basically get rid of that entire mess you had screenshotted two days ago
Yes - what I was doing was duplicating a different-sized widget and setting its parent to a 1x1-sized base widget.
A solution I implemented earlier today was to create a blank widget and set its parent to the base widget that has all the variables. This gets rid of the errors. Then I copied and pasted the designer contents (a button and a few images) and changed the size of the images.
Unfortunately, this meant I had to sacrifice some of the animation elements as it’s not possible to modify animation keyframe parameters at runtime (which is necessary because of the different sizes and which really is the crux of this whole problem), so it became pointless having multiple versions of the widget.
This makes the parent-child thing irrelevant as I now just have one widget. For each differently-sized inventory item I just add this widget and set the image brush dimensions at runtime and don’t bother with any size-dependent animations.
What I can do though - and I just don’t have the energy right now - is put multiple animations in this one widget to cater for each possible size (about two dozen now) so that I can play whichever one is needed at runtime.
The upshot is that I’ve effectively solved the problem and cut down the amount of BP script significantly. I’m quite pleased actually.
Thanks for the suggestion. I have been using an interface to get and set variables in the widget. The problem I had actually stems from the fact that it’s not possible to modify UMG animation parameters at runtime.
However, I’ve finally solved the problem (see last post below)!