How to create a button that, when clicked, loads and applies a texture on a surface in runtime?

Hey all,

For a new game project that I’m working on, I want to be able to apply images to surfaces by clicking on a button while in-game.
So far I only have a cube and a button (that doesn’t do anything yet).

I have a subfolder called “Textures” in my Content folder, in which I store various png files.
Whenever I launch the game, I will see a cube (or plane, in any case a flat object) which by default has no images or textures applied to it. When I click the “load image” button, I want it to apply an image from the “Textures” folder.
So far I have not decided whether I want it to choose an image at random or if the player has the option to choose an image, so for simplicity reasons let’s say I just have one image and the button should apply that one image to the surface.

Ideally, the image should be applied without distorted proportions, in other words it is not an issue if the image does not fill up the surface of the cube, as long as it is proportionally correct.

To recap, here is an image explaining what I’m trying to achieve.

I am still very much a beginner, so please be visual/descriptive in your responses! :slight_smile:
I’m using UE 4.10.

Thanks!

The proportional scaling part would be the most complex part here. Someone with more experience in the material editor may be able to advise how to do that there, but in this example I’ve just scaled the mesh to match the ratio.

  • Create a new material, imageMaterial_Mat. Add a texture sample, right click it and convert it to a parameter. Name it ImageTexture. Plug that into BaseColor.

  • Create a new Blueprint class which will be the cube that the image will be applied. Add a static mesh component and call it PlaneMesh. Here I would recommend a plane, of known size that has square UVs. A regular plane from 3ds Max at 100cm x 100cm will work. This plane will be scaled to fit the texture, it will scale down on the shortest side, so you could have a second mesh to maintain the border effect.

UpdateImage is a custom event. Click it and add an input parameter of type Texture2D, name it Texture and promote that to a variable. Also promote the dynamic material instance returned by CreateDynamicMaterialInstance to a variable on BegingPlay.

  • Create your widget blueprint. Mine is just a button, with this event:

Add a Texture2D variable. You can set that to be whatever you want, and when you click the button it will update the material on the plane.

First of all, thank you very much for helping out!

I’m having some issues however… I’m unable to connect the ‘target’ pin to the variables in both blueprints. Here are screenshots of what I have done so far (pretty sure I have copied everything you’ve done, but maybe you can notice a mistake?)

In LoadImage_BP, you may need to cast the result of the GetAllActorsOfClass to ImageViewer_BP. So drag off from the Get node, and type Cast o Image Viewer and you should see it. (You no longer need to do this in newer versions of the engine in cases like this).

What type is your image material? It should be Material Instance Dynamic. Try dragging of from the variable and searching for Set Texture Parameter, once it’s the right type.

I tried casting to ImageViewer_BP but unfortunately that did not work. I’m assuming I should connect the target pin to “as Image Viewer BP”? I’m using UE 4.10 which I guess is indeed an older version.

When I drag off from the variable I can’t find Set Texture Parameter, at least not with context sensitive checked on. I wonder if I’ve set MID the correct way, is this how it should be?

If you drag off from the As ImageViewer_BP on the cast, and type UpdateImage, does it show up?

In ImageViewer_BP, you haven’t got a material set in the source material there, but otherwise that should be fine. Hover over the pin on the Set ImageMaterial and check what variable type it says it is in the tool tip.

I just figured out that in LoadImage_BP, I was using the wrong node. I fixed that part now!

As for the Set ImageMaterial, it says Material Interface Reference. Is that what you meant?

It should be ‘Material Instance Dynamic Reference’. I done that in 4.12, but I don’t think it should be any different. If you can’t find it I’ll recreate it in 4.10 to check.

Ok, I just managed to fix that too. So now all blueprints can be compiled without error.

However when I click ‘play’, what happens now is that the plane already has the image applied to it. When I click the ‘load image’ button once, everything turns black. In editor mode, the plane has the WorldGridMaterial applied to it.
Do you perhaps know what could be going wrong here?

Have you given the Texture variable in your widget blueprint a default value? i.e. the texture you want to apply to your plane.

Also, check which way your plane is orientated, mine is like this:

129985-pl.png

If yours is aligned to the X axis, you’ll have to swap the Y and X, on the Set Relative Scale 3D node, so that Y is 1.

edit: Also, remove default texture from the material if you don’t want it to be immediately applied, or change it to some other placeholder texture. The create dynamic material instance is applying the material to the plane.

I tried several things, but it’s not working out the way I anticipated. At the moment I’m figuring out another way to set up my game and see what will come out, for now I will remember this information. Thank you very much, anyway!