Download

widget button to change object material - where to script the actions?

thanks guys.

this makes sense, what I’m making is a product viewer, and the menu interface thing I said is actually just a 2d interface on top of the window, that will always be there. it has some sort of expand and collapse actions to open more buttons, but that’s all UMG, the interface is always on top.

yeah I figured that this “get all of something” couldn’t be the best way, but it’s the only way I managed to call for the object. I know I must be doing something wrong, but I looked for it and still can’t add an actor reference to my object. clicking and draggin into the variable doesn’t work, a red dashed line appears, and the picker button is grayed out, so basically I’m struggling on the first step

I always overlooked game modes, since I do mostly archviz, and this product configurator is some sort of spin off for me, but still not really a game. I’ve read that documentation but I’m not sure if I need to set up a game mode for this, are there any particular reasons I should?

I’m trying to do this, but as I mentioned above, I’m struggling in the first step for some reason. my actor reference doesn’t seem to work or I don’t understand it well enough, even though I’ve read quite a few things about it

Having your own custom game mode allows you to have custom framework classes - without those, communication is much, much harder.

So I made a hud blueprint creating the widget there, and created a game mode blueprint. didn’t set anything on it but my base pawn as the default pawn class and the hud blueprint as the hud class. it displays the widget, but I still can’t get my object actor reference from any blueprints

Game Mode:

Untitled.png

Create widget in the MyHud:

intheHud.PNG

And in the LevelBlueprint, for example:

lb.PNG
[HR][/HR]
You can, of course, create the widget directly in the level blueprint - but then accessing it from inside of other blueprints is a bit more difficult.

yep, this I managed to do. only difference is that I’ve set my game mode in the project settings, not in the world override, but it’s working, the hud is being displayed, no problem

the problem is that the hud isn’t actually doing anything, I can’t give the buttons any kind of interaction with my object from inside my widget blueprint.

my intention is to change the material of my object in my scene, named “SuperSphere”. it’s an actor class blueprint with a sphere mesh positioned in the world

so in my widget blueprint I have some “on buton xx clicked” events, but I’d have to tell them do do something to my SuperSphere, but I can’t call it from inside the widget blueprint to make the buttons do anything to it

For something that simple you should honestly just create the widget in the SuperSphere object:

SuperSphere creates the widget which has a reference exposed on spawn. This will link these two together.

This is precisely what @StefanHohnwald said:

huh, now for some reason I managed to get that super sphere reference variable into the widget. I really tried doing it in every blueprint on the scene and couldn’t.

but that turned into another problem, the code worked with a “get all actors of class” node followed by a for “each loop”, but with the reference it doesn’t. btw teapot below is my supersphere

did I miss something?

Show us how you set the teapot reference. It’s the first pic in my previous post - the create widget node has an extra SphereRef pin.

Could you briefly tell what it’s going to be all about - a showroom with items the user can interact with, change their looks? Anything else?

When you do it with the reference and end the play with Escape, does the editor give any kind of error message, akin to “Got None while trying to get reference in node SetMaterial”?
If the reference doesn’t work, chances are that you didn’t set the reference variable properly to point to the SuperSphere actor.

I agree with Everynone, please show us how you set the TeapotRef in the widget, aka how you set the TeapotRef to point to the SuperSphere actor.

What you can do for debugging : Use a “IsValid”-node to check if the TeapotRef actually points to a valid actor. if not, you can print out an error message. If the error message gets printed, you know that your reference is invalid.

it returns two different errors:


Blueprint Runtime Error: "Accessed None trying to read property TeapotRef". Blueprint:  MaterialSelector Function:  Execute Ubergraph Material Selector Graph:  EventGraph Node:  Set Material
Blueprint Runtime Error: "Accessed None". Blueprint:  MaterialSelector Function:  Execute Ubergraph Material Selector Graph:  EventGraph Node:  Set Material

I also did what you suggested with the isvalid node, and turns out the TeapotRef is invalid. I really thought it should work, only managed to get that ref after some time burning my brain. I must be doing something very wrong

I just added a variable inside my widget blueprint side panel, and found the teapot there. like this:

then the moment I exposed it, “teapot ref” appeared on the HUD blueprint where the widget is being created, last item on the create widget node. i didn’t pin a reference to self there cuz it’s in the hud, not the actor, but since it says “teapot ref” i thought it was already referring to the correct thing.

right, so this is a product configurator for the costumer to be able to see the product in 3d with different materials and colors, cause it’s a little dificult sometimes for them to imagine just from a picture of the product and a fabric sample, how the product would look like with the materials they have chosen. it’s also impracticable to do renders with combinations of all the materials.

right now this is just a proof of concept, it will have only one chair spawned into the world, that is basically an infinite plane, and a 2d interface with two buttons, and when clicked each will show a sub menu with a few more buttons with material options for the seat or the structure. you can orbit/pan/zoom the camera around the chair, aswell as move the chair around.

if that works, it’ll probably grow from there to all our products, implement on website, have an app for vendors with all the products, have an app for costumers to download and place the products with AR into their homes, and finally, an add to cart option with the selected materials.

not quite a brief description, but that kinda explains why I’m being cautious with some aspects of this. I’m not sure where I want to have the widget created because maybe somewhere along the way I’ll try to test a way to add two different products into the scene and still be able to change their materials. maybe each product is going to have their own interfaces anyways cause the materials and parts are different for each product, but I’m not sure right now, so I’m trying not to commit, and even though I’m in the early stages, it’s a lot of work for me to try to figure this all out with little knowledge of ue4.

right now I have it working with a teapot, an interface to change the material of the body and the lid separately, and just finished adjusting the camera controls. the material changing code is not perfect as I’m using the get all actors of class node, but you know, I’m trying. I also think I got a working code for changing just some aspects of the materials dynamically, for example, instead of having a material for a black leather and a blue leather, only changing the base color parameter of the material.

You’re not putting anything in the Teapot ref… it’s stays invalid. The widget does know which teapot you mean - what if you have 5 teapots? If you’re doing this in the Teapot object just plug in self. This method of direct communication is OK when you need 1 to 1 comms - anything that grows in scope will need a different approach or will drive you mad when you need to rewire things for the nth time. Also, if you will never have more than 1 object at a time, (it hurts to say but here we go;) it’s probably OK with Get All Actors of Class.

Your description makes perfect sense, btw. A couple of extra question, will the widget that controls the visuals of the object be unique for every object or differ a lot? How does the user skip to the next item?

well it’s not in the teapot itself, it’s in the hud blueprint, so “self” doesn’t work, and I’m still no able to properly reference the teapot anywhere, really don’t know why or how.

so eventually I’ll have more than one object in the scene, and they will have different options in the interface, but the interface will be essentially the same, Not sure how it works yet but I was thinking of storing information on the objects regarding how many elements they have and the different material options that those elements can have, and then from the widget I’d just read those variables in order to create the appropriate interface for each object. should be easier (maybe not easier, but less work) than having a different interface for each object.

since in this proof of concept ther will be only one object and thus one interface, I’m not worrying too much about this for now, but I’m concerned on where the widget will be created, cause from what I’ve seen, there are many different ways to call for a reference deppending on what blueprint class you are doing it.

If you look at my example #9, you’ll see that I’m doing it inside of the SuperSphere - or Teapot, in your case. It’s the teapot that creates the widget and sends *self *reference.

Alternatively, you can use last pic in example #7 and have teapot access the HUD, grab the widget reference present there and store it for itself.

ok so I mistakenly thought that having the widget created inside the teapot would need a different widget for each object whenever I decided to try to place more than one object in the scene, but I suppose it’s just the creation, it could point to the same widget that would be created based on the object’s specifications, right? so I’m gonna try to have the object itself create the widget.

I assume that it’s a better choice than making it in the hud blueprint as it is currently?

EDIT: so I tried creating the widget from the teapot with a reference to self and it worked.

it’s really funny for me because I get really confused by this kind of interaction. like, inside the widget blueprint I created a variable, pointing it to the teapot actor class blueprint, and I thought that it would be enough to use it as a reference inside the widget blueprint, but that variable meant nothing for some reason. guess I had to define it? but then, the “create widget” node, which is in another blueprint, “found” that variable and added a connector with that variable in the node, even though I had just created and exposed the variable, didn’t drag it to the widget blueprint, didn’t connect it anywhere, but it appeared in the node anyway. cool I guess, but how did it find it and why? so I could define it? each time I want to make something interact cross blueprints it’s a totally different method.

It’s hard for me to make sense of these things, I’ve been watching quite a few videos about blueprints from the basics to more intermediate cases, but each case is so specific, I can’t seem to find a logic for these kinds of interactions.

On the contrary, you were right, this approach would indeed require one widget per one object. It’s a ham-fisted approach but it’s exceptionally easy too implement. Do note that one widget here mean one widget instance - it’s still the same widget blueprint, of course.

It is not a bad approach if you want the widget to remember the settings as the user scrubs through items and fiddles with the sliders and whatnot. When you come back to the previous item, the settings will be still applied, no need to save anything.

well I guess that’s what I meant, I thought I would have to code a separate widget for each object.

so how would you approach it? I want to make a material selector that works like this:

when I have one object in my scene, a simple button (let’s say button 1) will appear on the botom, and it will display the name of the object I have in my scene, and the behaviour will be related to that object. if I add another object, another button that behaves the same will appear, but with information from the second object. (didn’t figure out how I’m gonna add the object yet, but it doesn’t matter right now)

these single buttons when clicked will open another series of buttons above them, and their behaviour doesn’t matter, what matters is that the widget will work the same for every object, but the text displayed in the butons (product name, material name) and the number of buttons (number of elements in the object) will be generated dynamically based on information from the object.

would you make one widget and script this behaviour based on variables set on object construction?

It makes perfect sense. I would definitely use 1 widget for this and feed it data from the currently selected object. This widget would have a second hidden panel with additional buttons. I’ll try to put an example for you if you can wait until Monday. Stay tuned. :slight_smile:

**@fael097 **Sent you a private message. Let me know if it makes any sense to you.

got it, thanks! gonna take a look ASAP

yeah, absolutely it makes sense. the scene has some level of complexity for me, specially the game mode, but I understand the concept. the widget is getting info from the static mesh which is unique to each of the meshes, and then displaying this info, such as color and their names.

so what I thought is something like this, but instead of getting their existing information (such as color and name in this example), getting something I store into them, like number of elements and what materials each element can have assigned.

I do realize I could get the number of elements the mesh already have, but some products have parts that can only have one material, and I wouldn’t need a button for that element, so I think setting a number of “active” elements would be more appropriate.

so each product would have a variable for the number of active elements, and one array of materials for each active element. I see you commented that the showcase object should be hooked up to a database, and what I was thinking is if I could get the value for these variables from an XML table, so I could easily edit and add new material options without having to recompile everything.

so my interface would read the number of active elements from the product, and create that number of buttons, and each button would read the array of materials and create that number of sub-buttons.

I uploaded an html version of what I currently have, just so you can see how the interface would behave. gonna send it to your inbox. right now I don’t have any fancy variables, just hard wired each button to a different material.

so as you can see, right now I have a button labeled “color”, and it opens up 2 buttons labeled “body” and “lid” and each of them opens up another 3 buttons that apply a different material to the teapot part they are assigned to.

with the variables, the color button would create any number of buttons for active elements, and those would create another number of buttons for the array of materials each element can have.
for example:



<?xml?>
<teapot>
  <element name="body">
    <material>Red</material>
    <material>Green</material>
    <material>Blue</material>
  </element>
  <element name="lid">
    <material>Cyan</material>
    <material>Magenta</material>
    <material>Yellow</material>
  </element>
</teapot>


hope all this nonsense is understandable, I don’t know all the technical terms and sometimes I get lost in all of this, and I might be repeating myself as well :rolleyes: