Removing a widget with button press

I’m trying to make something simple as adding a widget to the viewport and display some text, then either have it removed after x seconds or have it removed immediately when the player presses the left mouse button.
But nothing happens when I set it up, and I have no idea how to bind the left mouse button into this event. The text never disappears, even when I remove the delay (I thought maybe telling it to delay the text for a few seconds plus telling it to remove it when clicking is confusing, but it’s not the issue)

Can somebody please explain to me what do I have to do? (for idiots, please)

And I only want this specific text widget removed, not all widgets.

Hello Hunxenlunx!

The trick is to put the “remove widget” code into the widget itself (I think).

My solution to this is rather “hairy”, but it does work and you can use it as a starting point to research this further.

The variable “IsRemoved” is set to false by default in this example:

1 Like

Hello Hunxenlunx,

why would that node “remove from parent” do not work? The only thing that comes to my mind is a question, how do you add your widget to the viewport in the first place?

In my project it works and I will post the answer for now. If you have any further questions - please, don’t hesitate.

Here is my function “Init Interface”, but it can be whatever you like, even an event:

Kill Interface can also be an event in your case (mouse button clicked):

Now, let’s ensure one more thing. Add to your event “Left Mouse Button” a Print Text node before “Remove from Parent” node. It should print whatever you wrote in your top left corner of the screen, when left mouse button has been clicked. We will see whether the event is ever called. It might be the issue, then write a comment. I need to know how and where you initiate the Left Mouse Button event.

You can also check this tutorial, step no. 19:
https://docs.unrealengine.com/latest/INT/Engine/UMG/QuickStart/4/index.html
and replace the node used there for this one:

Delay has nothing to do with it, there is just some magic behind the door and it comes back after a delay to the same place. Should work.

As you can see - I’m guessing a lot of things. Try them and write what are the results. I think we just lack information about your project and its structure.

Cheers!

// Taberu

P.S.
I also wanted to show you how to display simple text on your HUD but maybe try it by yourself in the future. It’s a bit more complicated. Useful when you don’t need to click on the text or picture you are showing on the screen and HUD draws every frame anyway.

Thanks a bunch you 2 for providing different solutions, I’ll try both of them!

I resolved the problem by setting “Auto Receive Input” in the class defaults to player 0, but I’ll experiment now with all of this.

Thanks for the answer. The problem was the left mouse button indeed. Changing it in the class defaults helped (enable player input), but I can’t set up the left mouse button properly in the player blueprint. I need it to remove several widgets, I wouldn’t know how to tell it in the player blueprint which widget to remove when.

What does work though is the solution from Fjellgnu.

I guess I could make something in the player blueprint to cast to the widgets and see which one is added right now and stuff…maybe that would be better, but it sounds super confusing and I don’t know how to cast yet (what exactly it is/does).

Wanted to try this tutorial though A new, community-hosted Unreal Engine Wiki - Announcements - Unreal Engine Forums

Maybe then I’ll understand more of it. For now I just want to get my game running without bugs.

About the structure, well, it’s not so complicated. I just want to press E to interact with something I look at (got this), then have text displayed on the screen (got this), then have it disappear after a delay (or mouse click) (got this).

Now I have to somehow set it up that the text does not overlap, and sometimes I have to draw the widget multiple times (because the text might change after clicking something once), so I need a bunch of bools. This is not really a problem I think, just something I need to do step by step.

But do you happen to know how I call a function I set up in an actor blueprint in the widget? I have no idea what goes into the target node, and it does not work either. I want to toggle UI back to visible after the text disappears, the “Toggle UI” works in the blueprint actor where I set it up, but not in the widget blueprint.

Casting is a C++ feature. Because I have to go to bed now, quickly:

Imagine you have an infinitely long line of drawers. A drawer is a box, every has the same volume. On every drawer there is a number, they are all sorted in order.
Now, you have fundamental types which takes, for example 4 boxes each (just assume you know exact number of drawers you need to store one fund. type). These are not our story for today.

Today, we have learnt a new ability. We can create our own object types. So we will create UnicornBase. What do we know about UnicornBase?
We can tell it contains 4 fundamental types, so we know the amount of boxes we need to store it.

The god said - create me a red unicorn. Pretty ugly, but do whatever he says. Let’s create UnicornRed. Wait a minute? We can use UnicornBase! That’s called inheritance in C++. You will surely understand it if you imagine how actually UnicornRed is created.

The moment to store our classes as physical objects in the drawers has come. We ask our mighty C++ to pick a number of a drawer we could start from. How it’s done, it’s another story. C++ now see our plans like that:

  • You want a UnicornRed… right, wait, but it inherits the base! So let’s start from it.
  • UnicodeBase, ok. 4 fundamentals.
  • puts 4 fundamentals into drawers.
  • Oh, you actually wanted a UnicornRed, let’s see what’s missing…
  • puts 1 color into the last drawer, after the base
  • So now you’ve got it! Remember the number it starts from!

What do we know after creating an object? We know it’s starting drawer (address). We know the base is first, then enhancement (color). We know the length of base and enhancement.

To understand casting, you need to understand one more thing. Mighty C++ gives you different Address (of a drawer) Card for every object type. He has different cards for every fundamental and for every object you have every declared. In my example, Address Card = drawer number, ok? Address Card type has to fit to the type which is stored in the drawer Address Card addresses.

So, you defined 10 more unicorns, UnicornBlue, UnicornPurple, UnicornOrange, and so on. Now you said to mighty C++ that you want to write down a list of every unicorn stored in the drawers (created objects). But C++ said:

  • I’m sorry, your list can contain only one type of my Address Card. So I can’t give you 11 Address Cards, you will drop them for sure!

What an as*hole you think, but you remember one thing! All Unicorns are starting from the base! So you can cheat the Mighty C++. Genius!

You created a list of 11 UnicornBase Address Cards. C++ agreed to give you 11 UnicornBase Address Cards and you stored them in your list. Now what?

You can cast! Just take an Address Card of UnicornBase, cast it to UnicornRed. What does it do? You know the length of UnicornBase, so you offset the address to point to UnicornRed!

Cast informs you whether it was successful. If there was no UnicornRed after UnicornBase, it means that it was indeed a UnicornBase, not UnicornRed. So cast returns NULL value (Address Card pointing to zero, dangerous).

So now, please, don’t be affraid and use your new ability! Search for “CastToYourClass” where “YourClass” is UnicornRed or the class you have created.

For the rest questions, try to look at my project PianoSequenceTutorial. It’s not perfect I guess but you will get the idea. As a homework you should improve the “InteractingObject” system to not only respond to Piano. Hint: use casting and story from above as inspiration.

Good luck!
Taberu

Hmm!

I am not sure what you are trying to do here. From the screenshots you posted it looks like you want to toggle the visibility of an actor in your scene from the widget? Is this correct?

EDIT:
Okay, so I think I have misunderstood this completely. Correct me if I am wrong here:

From what I understand you have a user interface in place. And then something happens, an event or something else that causes the Text Widget to be displayed. When that happens the user interface is removed and the text appears.

When the text widget is removed (either by itself or the left mouse button) you want the user interface to reappear, right?

If this is the case my suggestion to put the removal code into the widget was a stupid one. You can solve this be moving the removal code into the actor blueprint that calls the text widget. No casting required!

I don’t know what causes the text widget to be displayed in your code so I am using a keyboard event (E key) to trigger it. The code in the image does the same as my previous example (with some modifications) but is placed in the actor Blueprint instead!

It is also important that you have input enabled in the details section for the blueprint to allow the E-key Event to trigger!

115940-inputenabled.jpg

Hope this helps! Just ask if you have trouble!

Thanks again! Yes you understood it correctly, and I am aware that I could put your solution in the blueprint actor to avoid the casting, but is there really no way to do it with having the removal stuff in the text widget (like you suggested in your first answer?)

It REALLY bugs me that I couldn’t make it work because I could not find anything for the “target” of “Toggle UI” in the first screenshot.

Did you make the custom event by just plugging that last node in on top? Like telling it: This series of events (E → Create Blueprint Widget → Add to Viewport) is now called “Widget is on Screen” and this custom event replaces/equals the series on top?

Man, I wish I could work next to someone who know what they are doing like this and just ask whenever I don’t get something, that would be so much easier. Thanks a bunch, I’ll try to get your solution work now with the Toggle UI thing (and do a couple more of tutorials)

Thanks for the answer. I don’t 100% understand though. I do understand the theory but there’s a bump somewhere in it that I have trouble getting over. It kinda makes somewhat sense reading about it but when I have to work with it myself, I have no idea what to do.

Where does UnicornBase even come from?

For the example with the Toggle UI that I posted, I don’t understand why I can’t execute the function I have created in another blueprint. Why can I make a variable public but not a function? Why can the program understand to execute it in that one blueprint, but not in another one? And if it can’t because it can’t access components of the function because they are in my other blueprint, why does it also complain when I give it the components?

Does it not already know that this is a function from the blueprint called “BP_Texchange 2”? It’s even WRITTEN in it. What else does it want? It doesn’t want the camera, it doesn’t want the player, it doesn’t want the stupid UI_Interact component (which is a 3d widget and a component of the other blueprint I have the function in).

I even tried writing a NEW function in the text widget blueprint which did not work because now suddenly the UI_Interact component I was “getting” there required a target. What am I supposed to put in there as target? The blueprint actor itself? The mesh of it? I don’t understand the relations.

But maybe I’ll understand it the more I work with it. I’ll check out your tutorial. I’ll do ALL THE TUTORIALS!

I can try to explain the Target node. It can be confusing so take your time with this and don’t rush through it. And ask if something IS confusing!

The ToggleUI node tells you what its target is: “Target is BP Texchange 2”. So it may seem like a nobrainer that this node knows exactly where the ToggleUI event is, right? Here is the confusing part: It doesn’t!

So why not? BP Texchange 2 is a class and a class is like a definition or template that can be used to create an actor. It is not the actor itself.

The way you “create” an actor with the class is to drag it from the Content Browser into your map/level. When you do that it becomes an Instance of the BP Texchange 2 class (or an object created with that template).

You CAN (and will in most cases) do this many times to create several instances that uses the SAME class. And THAT is the problem for the ToggleUI node.

The target pin on the ToggleUI node is there to specify which Instance of the BP Texchange 2 class to use when the ToggleUI event is called.

Sorry, maybe I shouldn’t have involved C++ theory at all.

Fjellgnu already did explain you about target pin and that’s related to the question “where does UnicornBase even come from?”. It’s because UnicornBase is a CLASS. Class is like a plan, a schema, just a description. Only one class per name is in the whole project (so the name has to be unique). And where does it come from? We, as programmers or creator of a blueprint describes the class. Blueprints are somehow similar, we can treat them for now as our classes.

Now, as Fjellgnu said, when you put a class into the world - it become a living existence, physically placed in computers memory as many times as there are instances of it. When we store all the existences in the memory, it means we can assign different values to every one of them, because we know the address in the memory.

Location in the world is also a value stored within every one of the instances. Notice, that we can’t get the specific instance by our CLASS (description). Description only tells, what values it stores and what methods to use on these values. We can also describe a default value which is automatically assigned when the instance in the world is created and placed into the memory. It’s useful.

So, how to get the target pin? There are several ways. You can describe that actor class, which will spawn our class we need a target to - it will contain a target pin. Then, in the very moment of spawning our class we need a target to (the moment is also a description, an actor class) it will save that target from a spawn node to our target value in actor class instance.

The second way is to search through all the items placed in the world of specific class (World always knows and has a list of them). Then, determine if that’s the one instance we need by casting (if it’s a child class) or by location/value.

The third way is by collision detection. Collision is similar to determine by location, just done automatically by the system.

I will answer your other questions in half an hour. I just realized I doubled the theory Fjellgnu already explained and spent my whole time. But it’s really important to understand. :slight_smile:

Ohhhhh!! Ok, I get that. Thanks for explaining it. Now I only need to figure out how to get the instance in there.

I managed to set something else up yesterday which included getting a boolean from the blueprint actor in a widget, and it worked fine. Need to look at it again with in mind what you just wrote, maybe then I’ll even understand what I did there.

Man, how could I forget that? I think it is because I have this thing in the scene (it’s a cube with some stuff to try it out directly), so I totally forgot I can refer to scene objects in blueprints.

I even was close to figuring it out, but I had no idea how to get “the whole thing” (BP Texchange 2, which I saw as an object, not a class) into my widget blueprint.

Yeah, I somewhat understood now what you are talking about, so thanks again for explaining, really, to both of you, it’s so helpful and reduces some of the frustration I encountered. Thanks for taking the time and actually helping me with my actual problems and questions!

I’ll try later to make this work with a target, now that I got what you and Fjellgnu explained.

What I was about to do in general is this:

Imagine a game where you have several objects, and interacting with them creates a text on the screen (like a subtitle, like in an adventure). Sometimes interacting with an object twice will give you a different text the second time.

Now I wanted to make one object work with everything I need (this is what Fjellgnu helped me greatly with, setting up the text widgets and the mechanic to make them disappear).

Then I would have just copied that blueprint several times, rename it, change the mesh, and put it in the scene.

Would that mean that I would have created several CLASSES, and each of them would have 1 instance in the scene, and I could have instead just used only 1 blueprint and change its instance directly in the scene?

The problem with this I also still have is figuring out the absolute basics for the class. In my example is a text in the class that of course does not need to appear for every instance, since the objects are all different with different texts. I would need to write code that basically says: “Insert text here”, then gets the text variable, then checks if a second text is available, and if so, gets the second option, and probably I would have to store the texts in an array.

Instead I enter the text manually for everything because I can’t wrap around my head yet how to make a system that works with different things. Not every object gives you different texts, some give you 2 or 3 lines, some give you 1, some let you interact differently and then give you text… I don’t know if I could come up with a general solution for all.

BTW yesterday I also encountered one of the typical bumps I used to have trouble getting over with, also with different ways of programming/coding (I got taught (more or less) a different but also beginner friendly way of coding during studies)

You create a custom event node, then name it somehow, and there it is. Your custom event Let’s say it’s called “UnicornPoop”
Now you can right click and choose “UnicornPoop” from the context menu, and it gives you a red node called “UnicornPoop” and you can start using it, starting a series of events with it.

But nowhere you have it defined, it’s still possible, even though the game does not know what “UnicornPoop” even means.

To give it a meaning, you have to plug it somewhere in the end of a series like Fjellgnu did to tell it “this and this and this equals UnicornPoop”.

But to access this node yesterday I plug at the END of a series of events, I had to CREATE it first.

And this is what messes with my mind. Somehow it seems like the wrong order, and stuff like this has bugged me ever since.

Maybe for others it makes perfect sense - first you create something, then you can use/access it. But for me it seems like the other way around - I create something useless, that I then can define. And until I have done this, something utterly empty and useless exists.

I guess I have to think of this like of little bags I have to crochet first. I can’t take a handful of marbles and turn them into a bag filled with marbles. The crocheting comes first until I can put something into it, and until I put something into it, a useless bag exists.

Do the following:

  • Create blueprint, choose parent “Actor”, name it “InteractingObject”.
  • In InteractingObject blueprint add box collision component as a root.
  • Set a collision inside blueprints, in Character there is a sphere, and in InteractingObject use box you added. Use for character a collision preset of a Pawn, and in InteractingObject of a Trigger.
  • In your Character blueprint, in variables, not in locals(!), add, search for “InteractingObject”->reference.
  • In your Character blueprint, modify event graph, add event “OnActorBeginOverlap”, it comes with argument of “OtherActor”. Cast that OtherActor to “InteractingObject” and if it succeed, save the reference. To save the reference: pull the reference created above in variables to the graph, choose set, connect “OtherActor” from event to set node.
  • In your Character blueprint, in event graph, add event “OnActorEndsOverlap”, cast “OtherActor” to “InteractingObject”, if it succeed, set the reference without connecting it (it sets the reference to NULL, which means 0. It is special case which means it’s not referencing anything, cast always fails in that case and isValid also fails, it’s useful).
  • You can add here, in Character, the system to show “Press E to interact” or “Press LMB to interact” on the screen when Character overlaps. Do it using widgets or, as I did in tutorial, HUD class.
  • More importantly, set input in Project’s Settings, add input event in Character’s event graph and connect it with function “StartInteract” (you can add your own functions (these are called methods) within blueprint.

Before we add functionality in “StartInteract”, let’s create specific interacting object:

  • Create blueprint, choose parent “InteractingObject”, name it “Chest”
  • Go to “InteractingObject” blueprint you have created before, add a text variable and name it “DisplayText”. You can assign a default value to it. Now, open the “Chest” blueprint and you will see that “DisplayText” should be now available in ‘details’ tab of our “Chest” blueprint. Change the value to “You have opened a chest!”.

Now, let’s create widget for interacting, in content browser create Widget, name it “InteractionWidget”. Place text on the screen inside the Widget editor.

Return to “InteractingObject” blueprint. Add function “Interact”. Inside, place the nodes responsible to attach the widget to the player’s viewport. After them, pull the reference to your “InteractionWidget” and using it - set a value of text variable you have placed on the screen, set it by value of variable “DisplayText”.

In “InteractingObject” you can create a simple Delay node, which will trigger after 2 seconds a detach from viewport. After detaching, you can set a bool flag, that the object was used. Also, you can change the “DisplayText” to another.

Now, as we explained in comments, in blueprint of “Chest” you can add specific MeshComponent. To place a “Chest” to the world, drag it from Content Browser to the game. It’s going to instantiate the object of blueprint class “Chest”, you will see in the World Detail tab a specific name, for example “Chest_01”. You can instantiate as many chests as you want and in every chest you can change the default value of “DisplayText” to original message.

To create a different object to interact with, use a parent “InteractingObject” and add different MeshComponent or AudioComponents. That’s how it works.

Don’t forget to choose this answer if it fits your needs, thanks.

Good luck!
// Taberu

I just want to put in a quick comment on the Custom Events. Just be glad you can’t call an Event that does not exist. If you could do that and you start creating calls to many events that does not exist you would lose track of them fairly quickly and your blueprint would end up a total wreck.

There are so many potential pitfall with something like that and I think this is the main reason why you can’t do it.

EDIT: Taberu, what are your thoughts on this?

I simply don’t get why the sheer act of creating it in the Event Graph is such a deal.

As far as I know, after I created with “add node” this red node of the custom event, I can delete it right away. Why can’t pulling a node from a series of events result in automatically creating a custom event as well? I mean the result would look the same.