Blueprint Communications | Live Training | Unreal Engine

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Zak Parrish: Hello and welcome to the Unreal Engine training stream live from Epic HQ. I am your host today, Zak Parrish. Today, we are going to be talking about Blueprint communication. We have a lot to cover today. I am going to give a couple of general disclaimers. One, this might run a little bit long. I am going to try to keep it around 90 minutes, but that is me just guessing. I have no idea how long this is going to take. If you are new to this or you are really interested in the topic of Blueprint communication, I expect you to be taking notes because there is a lot of information we have to cover. There is so much information that I am doing something that I generally don't do. I actually made a slide deck that we are going to be reviewing as we go through all this. On that note before we even get started, take a look at the screen real quick. Jump over to unrealengine.com/resources. This page is supposed to be on the other monitor. I will use that monitor instead and it will be great. At unrealengine.com/resources, you can find the slides I will be going through today. If you grab those slides, you will probably get to take maybe half as many notes. You should still be ready to write things down. Again, there is a lot of things to cover here. With that out of the way, let's go ahead and get started. I will swap out the monitor I am doing important things on and we will do important things on this monitor instead, which will be great. I will press the mighty Present button and now, things look all kinds of official. Look at this: Blueprint Communication and You. It is complete with disco lights because that is amazing. I am not going to just read everything to you verbatim. I am expecting you to look at what is on the screen, and read it while I talk through it. In between each section, we will pause and take some questions after a brief demonstration. Then, we will do more questions and answers at the very end. For starters, what is Blueprint communication? I am going to click the Allow button to get that dialog box out of here. I want you to think of Blueprint communication as a way to get two (2) objects to interact, or to communicate in some form or fashion. The classic example is a Light Blueprint and a LightSwitch Blueprint; or for that matter, even a Character and a LightSwitch Blueprint. How do you get those two (2) Blueprints to send data back and forth to one another? It is useful for things like telling an object to do something, which is generally by way of sending an event or calling a function. Blueprint communication is also useful for querying things like the status of something, its state, a property or a variable, or getting back any kind of results. Now, I did have a programmer point out to me that property values and variable values are the same thing. I only separated them because there are properties that exist on an object without variables. If you are totally new to the world of scripting, it is probably useful for you to know that sort of thing. A simple primer of things you should just know. Unreal Engine 4 (UE4) has no way to just send a single broad signal out to everyone. There is no way you can say, "Something happens and anybody can just magically pick up that signal and just go from there." This was a thing. This did exist way back in the Unreal Engine 2 days, but it wasn't great. We don't do it that way anymore. Communication is always going to involve some Blueprint that is sending and one that is receiving. You are going to hear me say that a lot today. I am going to call them the sender and the receiver. There are a lot of different words you may end up hearing as you do this kind of work. You might hear things like instigator, which I didn't want to use because it gets kind of overloaded. I am going to keep things fairly simple. There is a Blueprint that is responsible for driving the communication which we will call the sender, and a Blueprint that is receiving that communication. It gets a little interesting, and we will explore why it is interesting as we move forward. Communication is always going to require a reference at some point. In other words, that means either the sender or the receiver has to know about the other one. This is probably going to be the trickiest thing when you first get started. How do you get that initial reference? How does Blueprint A even know about Blueprint B, so it can communicate with it? As stated above, the reason you need these references is because there is no broad spectrum communication. Again, you can't just shout out into the world and expect random things to hear your message. There has to be some specific way of saying, "You! I am talking to you, and I want you to do something." Now, the next key point. All Blueprint communication is one-way, technically speaking. This will confuse some people, but I want you to stop and think about it for just a minute. Blueprints can actually send data back and forth, but it is going to require both Blueprints to set up their own individual paths of communication. What do I mean by this? You have a sender, and you have a receiver. Sender to receiver is always mono-directional. Here is where it starts to get complicated. A sender can get a return value from the receiver. For instance if you are sitting across the room from me, I can say, "Tell me how old you are," and you just send back that information. In Blueprint terms, that is like saying I just called a function on you, and the return value is you telling me the age number. I get some data back, but I still had to start the process. I had to reach over and give you some sort of a command, and that is how Blueprint communication works. Beyond that return value if you had something else you wanted to communicate to me, at that point you become the sender and you would have to send me some data, or make a request from me that I could send back as a return value. As you get deeper into Blueprint communication, it will help if you remember that generally speaking, Blueprint communication is a one-way street with the exception of things like return values. In that way, queries are possible through Blueprint communication. This ties into return values, but queries are still initiated by the sender, which I have kind of covered. For today and for our purposes, there are 3 primary Blueprint communication methods. We have direct communication, which we will talk a lot about casting to make that possible. If you have heard the word casting a few times, then you know where it is going to tie in. We have Blueprint Interface message calls, and we have Event Dispatchers. There may be some other types of Blueprint communication out there in the world, but in most cases, they are probably going to be an extension of one of these 3 types. These are the 3 Blueprint communication methods we are going to be focusing on today. Since there are different types, how do you know what kind you can use? If you are totally new to Blueprint communication, this part is probably going to make you curious. It will bring up more questions, than it does answers. This is one of those things where the newer you are, the more this is kind of like seed planting. Later on once you are more used to Blueprint communication, you will be like, "Oh, I finally get what Zak was talking about when he carried on and on about when to use the different types." What I have done is try to simplify this into two (2) key questions. If anybody wants to come back and say there are lots of things to consider, you are probably right. I was trying to keep this simple. The first question is, what is the flow of communication? Is the sender pushing some data out to a receiver? Maybe it is something like setting a value on the receiver, or even just calling a function on the receiver. In that case, the sender is doing something and it is being received. In those cases, you will be using either direct communication or Blueprint Interface communication. There is another layer to figure out which of those two (2) to use, but we will talk about that later. In terms of the flow of communication, there is another side to that. Are the receivers actively listening for the sender to do something? In this case, the receiver is doing a little bit more of the heavy lifting. If that is the case, you are going to be using Event Dispatchers. If conceptualizing the flow of communication is a little confusing right now, don't worry. Go with it. It will become clearer as we go through this. Next, our second question is which party can get a reference to the other? Remember from earlier, we said Blueprint communication always requires one party (the sender or the receiver) to get access to the other. If the sender has a reference to the receiver, then you are either using direct communication or you are using Blueprint Interfaces. If only the receivers can get a reference to the sender, then you are using Event Dispatchers. It becomes easier to answer these questions as you get deeper and deeper into Blueprint communication. If you grab the slide deck and you are just following along, put a checkmark on it. Grab a magic marker and put a checkmark on your monitor; it works great with PowerPoint. [Laughing] Then, you can come back and look at this slide later when you need it. That is our primer. We won't worry about questions right now. We are going to talk a little bit about direct Blueprint communication. Then, we will answer questions just about direct Blueprint communication. Then we will talk about Blueprint Interfaces, and then take questions just over that. Then we will cover Event Dispatchers, and then take questions over that. Then we will have a great big wrap-up, if you have any remaining questions. Let's focus on direct Blueprint communication. High-level concept: this is just one (1) Blueprint talking directly to another Blueprint. A sender will gain access to a receiver. The sender gets that critical reference which you have to have. The sender can then query data and variables. They can say, "Hey, how old are you? What is your Health? How much Armor do you have before we can start chiseling away at your Health Bar?", etc. The sender can send data and it can update variables. One (1) Blueprint can say to another, "Hey, I am going to set your Health back to 100% because you just picked up this Health potion," or something. Or, the sender could call functionality on the receiver. The sender could say, "I am forcing you to jump because you just landed on a springboard," or something like that. Now, this is always 1-to-1 communication, and not 1-to-many. This is just one (1) Blueprint talking to one (1) Blueprint and that is all, and that is all it will ever be. You can use tricks of flow control in order to talk to a lot of different things. You could use a For Each Loop, for example. You could say, "Loop through these n number of Blueprints, these 152 Blueprints. For each one (1), send them this signal." But, each iteration of that For Each Loop is still 1-to-1 communication. There are some 1-to-many examples for communication. We will talk a bit about that with Event Dispatchers, but that is a different thing. Next, direct Blueprint communication and when to use it. You are only going to use direct Blueprint communication when you know the following. You know what the sending object is going to be. You know what the receiving object(s) are going to be. Or, you at least have a clear way to get a reference to the receiving object(s). For example, like maybe using an overlap node or using the Get Player Pawn node to get a reference to the Player, and that sort of thing. You know what data or functionality you're going to have. You already know that variable name or property name. Essentially, you know everything. You know what is going to happen. You know who it is going to happen between. You just need to know when it needs to happen. You need to drive that. If you don't know everything, like if you don't know what Blueprint is going to be the sender or the receiver, or you don't know what property you are going to be talking to; then, you will probably with direct Blueprint communication wind up having to use a lot of if statements or Branch nodes in Blueprint. If I tried to interact with a Box, then open the Box. If I tried to interact with a Light, then toggle the Light. This method is generally not good. If you find yourself using a lot of nested if statements for communication, you should probably be using a different form of communication. This also ties into casting, which we will talk about in a few minutes. In short and so you will have heard this at least a little bit as we go forward, casting is just a way to verify who you are talking to. If you are doing something like: was this a Door? Yes or no? Then, do something. Was this a Light? Yes or no? Then, do something. If you are having to dig through and ask those kinds of questions over and over again, you probably shouldn't be using Direct Blueprint Communication. Just keep that in mind. Next, Direct Blueprint Communication in action. How does it actually work? The sender is going to get a reference to the receiver. There are so many ways to do this that I could spend the rest of my day explaining them all to you. Here are some examples you will frequently run into. There is lightning. That is amazing. We can assign a reference at the beginning of the game. On BeginPlay, we could get a reference to some Actor and just assign it somewhere. You could do it On Overlap. For example, the Character walks up to some thing and that thing has a volume in front of it which gives you an overlap. Since there was an overlap, you now have a reference to the Character because he just walked into the volume, and now he can start doing things. I tend to not encourage this, but you can use Get All Objects or Get All Actors of Class nodes. I see a lot of people who are very new with Blueprint who use these. I don't recommend you use these nodes, but they are there. Every once in a while you may find you need to fall back on it. Just remember using either of these can be very slow, especially if you have a lot of objects in your scene. That is just worth mentioning. Once you have that reference, the sender may need to cast this reference to the thing it wants to talk to. If you are totally new to casting or if you think casting is some sort of dark programmer magic that is all kinds of scary, fear not. Casting is actually very easy. We are going to make it pretty simple before the day is out. Casting is just a way to test and verify what you are talking to. If you need to send a message to your best friend Bob, you pick up the telephone, and somebody is on the other end of the telephone; what is the first thing you are going to do? You are not going to deliver your message. You are going to say, "Hey, is this Bob?" Once that comes back with yes, then you will deliver your message. Casting is exactly the same thing. Casting is just a way for you to make sure you are talking to the right thing before you start trying to communicate with it, and do all the fun things you want to do. We will cover casting in much more depth, a bit later. If the cast is successful, then the connection is complete and you are ready to begin communicating. The sender can now send data. The sender can query data from the receiver. The sender can also call functionality directly on the receiver. Here is generally what casting looks like from the sender's perspective. You will have an incoming execution wire that is going to hit the Cast To node. Here is your reference. The reference variable could be populated from anything. For example, it could have been populated because of some overlap further up the script. Then, we have a wire that goes out if the Cast To succeeds, and a wire that goes out if the Cast To fails. As Pawn is the data wire, which is going to give us access to the functionality for whatever it is we Cast To. We are going to see this live here in just a couple of minutes. Before I show you, this is where if you are new to casting I hope you were listening earlier, and brought a notebook or something you can follow along with. I find Blueprint Casting confuses a lot of non-coder types. Programmers are a little more used to the term casting because casting is a programming term. If you have been writing code, you are almost certainly used to this concept. As I mentioned earlier, just think of casting as a way to verify what you are talking to. Once you have cast to a given type, only then do you have access to it. Only then, you can talk to it. Only then you can ask it things, you can tell it things, and you can call functionality on it. If a cast fails, you can always cast to something else. We get a reference to some Actor or object and then we ask some questions. Was it a Door? No. Cast it to a Light. Was that successful? No. Was it a Weasel? If that was successful, then we can do something to the Weasel like set its bWearingAPartyHat Boolean to True, or whatever. Again if you find yourself having a lot of nested behaviors and you have to ask 20 questions before you get to do anything, you should probably rethink how you are communicating. But it is good to know you have the option of casting. If you already have a reference of the proper type, then you do not need to cast. What do I mean by that? If you walked up to a Door and you knew you had a Door so you populated a variable in your Blueprint of type Door, then you don't actually need to cast to it. In fact when you try to cast, Blueprint will warn you and say, "This was a Door when you got here". This cast is always going to return true. In that case, you can snip out the Cast To node. The message is just a warning; it is not an error. Be sure you click Compile, and Blueprint will do its best to tell you when you are overcasting. Next, casting and object orientation. Here is the fun bit of my job. I travel the world. I go all over the place and I help people understand how all the different systems in UE4 work, primarily the systems in the editor. I am still not the world's strongest programmer by a very long shot, but I talk to people a lot about Blueprint. Since day one, Blueprint has been marketed as scripting for the non-scripter and non-coder like people. Blueprint is visual and it appeals to visual people. All of that is true and valid, but there is more to it than that. The other side of it is in order to really use Blueprint, you have to be thinking a little bit like a programmer. You don't have to be a programmer, but you have to know some key programming concepts. One of those concepts is object orientation. The reason is that Unreal Engine itself is built on an object oriented framework. You are most likely going to be using that framework to make your games. In fact if you are just using Blueprint you have to use that framework, so you need to know how object orientation works. On the left hand side, consider the following class hierarchy. I have indented the names to denote inheritance. You might have seen a hierarchy like this before, even inside UE4. You have Object, Actor, Pawn, and Character. Then underneath Character, we have four (4) different playable Characters you could maybe possess and drive around your level. We have Wendy, Michael, John, and Peter. Think about this from a casting perspective. Refer to the data I have over on the right. Casting to Wendy will give you access to things that are specific to Wendy. For example, what is her nightgown color? Obviously she was sleeping when Peter flew in through the window, but that is a whole other story. However if you Cast to Wendy as part of your Blueprint, you can't access things that are specific to Michael, John, or Peter. You can't ask Michael what kind of top hat he was wearing. Or, you can't ask Peter what color his dagger was. You don't know these kinds of things because you have cast all the way down to Wendy. If you needed to access something that was available to all possessable Characters, you would actually cast to the next class up in the hierarchy. For example, let's say all the possessable Characters (Wendy, Michael, John, and Peter) all have a Pixie Dust value for how much they can fly. That property value would exist on all of them. You wouldn't want to set the value individually for Wendy, and set it up again for Michael, and set it up for John, etc. You would set the value up in Character so they would all inherit the value. If you needed to query or change that value for any one of these Characters, you can cast up to Character instead of casting down to them. If you are totally new to programming, this is one of those things this can be a little confusing. Bear with it and take some notes on this. The more you start actually handling Blueprint communication and casting, this will make a lot more sense. Continuing on, not all of these cast levels are guaranteed to give you access to the functionality you need. If you cast to way too high of a Parent Class, that is going to lock you out of a specific functionality that only the children have. For example, a Character is going to have some sort of a physics state such as swimming, walking, jumping, etc. If you cast up to Actor, you would have cast too high because none of that data was implemented in Actor. You won't find the data you are looking for. On the other side of that, casting down too far a Child Class will lower the overall flexibility and eliminate the possibility of accessing sibling classes without further testing. You have to think about this intelligently. It ties into making sure you are building your Blueprint Classes and keeping that class hierarchy in mind. If you are creating several different types of objects and they have to have common functionality, then it is possible they should have the same Parent Class and build up from there. Obviously, there is a lot to that. That is one of those things where we are kind of getting into side topics a little bit like the UE4 framework and how to build classes of objects, and Child Classes, etc. All of those topics tie together and are very important for Blueprint communication. Just keep that all in mind. Remember, shared concepts belong in higher base classes. Don't duplicate your work. If you find yourself copying a selection of nodes between sibling classes, then you are probably doing it wrong. Put that functionality up in the Parent Class so the children inherit it for free. Enough beating that dead literary character. Let's demonstrate Blueprint communication and direct communication, and then I will take some questions. I will bring the editor over. If you are following along or you want to do this on your own, I am using the Third Person Blueprint template. For starters, we are going to set up a very simple system to hurt the Player. We are not even going to use Blueprint communication to do this. Mostly for academic purposes, we are going to show you how to take damage and apply that to the health of a Character. We have to set up Health. Then we will create a Blueprint that can communicate with our Player, cast to it, and then it will affect some properties, specifically the Health property. Then, we are going to heal the Player and talk about how all of that works. For starters, this is just preparation. I am only showing this so you can follow along later. If I am moving too fast, don't worry about getting me to slow down. Just take notes, and then come back when the video has been archived and follow along at your leisure. Then, you will have a Pause button. We are going to start in the Place Mode in the Modes panel. Click on Volumes and scroll all the way down to the bottom. We want a Pain Causing Volume. Drag Pain Causing Volume into the world. Pain Causing Volumes do not render in the game. You cannot see Pain Causing Volumes. We are going to put something on the ground to make it a little easier to see. In the Modes panel, select Basic. Drag a Cube onto the floor. Press R to use the Scale tool, and scale the volume down a little bit. I probably don't even need to scale it, but I did anyway. Press W to use the Move tool and move the Cube so it is just sticking up out of the floor. Press R to use the Scale tool and scale it up so it pretty much fills in the floor space of our volume. Press F to frame up on the Cube so we can see it. This does not have to be perfect. If you are spending a lot of time getting it just right, you are probably overdoing it. Then in the Modes panel, select All Classes. In the search bar, type and select "Text Render". Drag Text Render into the world. It is always facing the direction I don't want it to face, which is fine. Press E to use the Rotate tool and rotate the Text Render 180° around, and rotate it 90° back. Press W to use the Move tool and drag the Text Render into the air to get rid of the flickering caused by Z fighting. In the Details panel, set the Text to "PainVolume". That looks pretty good. In the Details panel, click the Text Render Color property and I am going to make the text red. Now the volume is labeled and everything is good. Real quickly, select your PainCausingVolume in the World Outliner. In the Details panel, set Damage Per Sec to 10. Here is a quick, fun fact. UE4 includes a setup for damage. In fact, we are looking at it. We have things like the Pain Causing Volume, which has its own Damage Type and other properties. It doesn't have an integrated idea of what health is. Damage is there, but you have to determine what that damage is actually going to do. Open the Blueprints folder in the Content Browser, and Double-click to open ThirdPersonCharacter. I will dock the Blueprint Editor to the top so everybody can see. I am going to go to a blank area of the Event Graph. Again, I am not worrying about Blueprint communication right now. I am just setting up a common test space so you can follow along while we do all of this. Right-click in the graph, and type "any damage". Select Event AnyDamage. This takes in a certain amount of damage, and it is going to do some things to it. Again, we have no concept of health. Let's fix that. In the My Blueprint panel, click the Add New button to add a custom variable. Call this variable "Health". In the Details panel, set Variable Type to Float. Click Compile. In the Details panel, set the Health Default Value to 100. A Health value of 100 is pretty common among video games. There we go. We have a base Health of 100. Hold Ctrl + Drag Health into the graph so we get a reference to it. Drag off Health, type "-" to subtract, and select float - float. Plug Damage into the float - float node. Hold Alt + Drag a copy of Health into the world. Plug the Float Return Value into Health. Plug Event AnyDamage into the Set Health node. It is pretty easy to see what this is doing, right? When we have incoming Damage, take our current amount of Health, subtract the Damage away, and set the result of that to our new Health value. We are indeed steadily dying. Next, let's print that information to the screen so we can see something happen. Right-click in the graph, type and select "Print String". Obviously hence the name, the Print String node takes in a string, which is why the pin is magenta. If you try to plug a green float into a string, UE4 creates a node to convert the data variable types. Leave the node there; it is to your benefit. It is pretty easy to see how this works. Let's test it real fast. Click Compile. Go to ThirdPersonExampleMap and click Play. Here is our character. He runs over, stands on the pad, and you can see his Health steadily dropping: 70, 60, 50, 40, and so on. Awesome. None of that was Blueprint communication. [Laughing] Now, let's fix that and do something where we have Blueprints communicating. For this, we need a Blueprint. Right-click in the Content Browser and select Blueprint Class. Select Actor. Anything that can live in the level will be just fine for us. Click Actor. Call this class "HealingVolume". Double-click to open HealingVolume. Here we are. Now, we are going to keep this very simple. In the Components panel, click Add Component, type and select "Box Collision". There it is. Call this Box Collision "Volume" to give it some kind of meaningful name. In the Details panel under Shape, set the Box Extent X, Y, and Z values to 200. That gives the Box Collision the same default size as the Pain Causing Volume from earlier. That is the only reason we are using those values. Next, go to the Event Graph. We are going to cheat and make use of some of the events that are waiting for you to do something to them here. We have Event ActorBeginOverlap. This means some other Actor is overlapping with our Blueprint, and we have a reference to that. That reference is the very heart of all Blueprint communication. We have that reference. There are other ways we could do this. We are not going to do use these methods because they are not efficient. We could Right-click, type and select "Get Player Pawn". As long as it is as Player Index 0, which it is for a a single-player game, we would have access to some Pawn Class. It is not necessarily the same class as our Third Person Character Blueprint. Just a quick note. You can go into any Blueprint and click the Class Settings button in the toolbar. In the Details panel, you can always see what the Parent Class is. The Parent Class of ThirdPersonCharacter is Character. Character is a Child Class of Pawn. Go to HealingVolume. Drag a wire off the Get Player Pawn Return Value, and type "Health". I don't get any results because it doesn't know what Health is. There is nothing we can do here because this is the wrong class. We would have to cast to this. Type "Cast To", and select Cast To Character. Now, it is a Character. Drag off As Character, and type "Health". We still get nothing because we didn't implement Health in the Character. We implemented Health in the ThidPersonCharacter, which is a very specific class. Drag a wire off Return Value, type "Cast To" and select Cast To ThirdPersonCharacter. Drag a wire off As Third Person Character, and type "Health". Check it out. We can Get Health and we can Set Health. Now, we don't really need the Player Pawn for this. Select Get Player Pawn and press Delete. Notice as soon as I removed the node, the Object is greyed out because this is a wildcard value. Plug the Other Actor wire from Event ActorBeginOverlap into Object. Now, what is this doing? It is asking, "What was that thing that overlapped with us? Let's make sure it was a Third Person Character." Plug Event ActorBeginOverlap into Cast To ThidPersonCharacter. Drag off As Third Person Character, type and select "Set Health". Plug Cast To ThirdPersonCharacter into Set Health. What are we going to set it up to? We are going to set Health to 100. Now, we are hard coding that value. If I was being hard-core about this, I would create a separate variable inside of our Third Person Character Class called something like MaxHealth. This would hold the maximum default Health our Character has. As soon as we verify it was the Third Person Character, we would get the Max Health, and assign that to the Health value. We are not going to do all that. That seems a little over the top for this example. I just want to mention it. This is all we are doing. If something overlaps we make sure it is the Third Person Character, we set its Health to 100, and everyone is happy. Click Compile and click Save. One more thing real quickly. Right-click in the graph, type and select "Print String". Plug Set Health into Print String. Set In String to "Character has been healed". Expand the node, and select Text Color. In the Color Picker, choose a green because it seems like a healthy color. Click Compile and click Save. Go to ThirdPersonExampleMap. Let's get this guy into the world so he can start doing some stuff. Drag HealingVolume into the world. It looks like a Scale value of 200 x 200 x 200 is twice as big as it needed to be. I am going to scale this down because size doesn't really matter. Press W to use the Move tool and move the HealingVolume off to the side. Select the Cube and the Text Render, hold Alt + Drag a copy underneath the HealingVolume. Select the TextRender. In the Details panel set the Text to "Healing Volume". Select the Text Render Color and choose a green. Awesome. Now, we can test this. Click Play. Run over to the PainVolume. Health goes to 90, 80, 70, 60, 50, and so forth. Go to the Healing Volume. The Character has been healed! Awesome. Let's run back over and get hurt again: 90, 80, 70, and so forth. We did actually heal the Character, so that is Direct Blueprint Communication. How did it work? Let's review one more time before we move on. Select the Healing Volume and go to its Event Graph. The Blueprint gets a reference to a receiving object. The Blueprint casts to make sure that is exactly what it wants to talk to. Once it has finished this cast and the cast has succeeded, we now have access to all the properties on that object. We are going to set the values to something else, and we are going to send it some data. Then, we are going do our own thing and print some information out to the screen. That is it. We can only do this because we knew who the sender was going to be, which is going to be this volume. We knew the receiver was going to be the Player Character. We knew what data we were going to send. We knew we were talking to the Health value and sending it some number. If we didn't know all of those, we would have to start asking a lot of questions. For example, Cast to ThirdPersonCharacter. Or even Cast to Character. Was that successful? Yes or no? Was it the Third Person Character? Yes or no? Does it have Health? Yes or no? You would have to start asking all of these questions before you began communication. Click Compile and click Save. There is our simple example of Direct Blueprint Communication. Let's jump back over to the PowerPoint. Are there any questions about all of this? To help with questions, I have some information over here. Some of the questions I am seeing pop up in our list of questions are for a little bit later in the stream. If I know we are going to talk about it later, then I am not going to worry about it right now. How can we use the inherit classes between Blueprint Classes? I really wish I could just reach through the screen and get you to rephrase that question because I am not sure what you mean. In order to inherit functionality from one (1) Blueprint to another, you simply need to make a Child Class. For example, let's say I need a different kind of healing volume that didn't actually heal you up to 100%. Maybe it over healed you up to 150. That would be pretty cool, right? The healing volume could have the same basic functionality. I could Right-click HealingVolume, and select Create Child Blueprint Class. It is currently called HealingVolumeChild. Call this class "SuperHealingVolume". Go to the Event Graph. Check it out. Event ActorBeginOverlap has a call to the Parent: ActorBeginOverlap. This is all of the functionality for the Parent Class. We can override this functionality if we want to. We can delete this wire and add our own functionality, which would essentially be overriding. Or, we can add further functionality beyond this. We could grab the Character and add more Health. We could call any other functionality on the Character we want. The point is because this is a Child Class, it can do everything the Parent Class can do. The Child Class has every single variable of the Parent Class as well. I hope that helps answer that question. If that question comes back up, just ask again in a slightly different way, and we will go a little deeper. Let's see. You have to give me a second to read some of these questions to make sure they fit in with what we are talking about. Question, why is there a Pain Causing Volume? Wouldn't a general volume with customizable functionality be enough? Sure, it would. It is just a convenience thing. It is one of those little quality of life things that turns up in a lot of games where you are going to want to cause damage to something. But I actually agree with the spirit of where your question is coming from. Why do you have Pain Causing Volumes, but you don't have health on your default Character Class? It is just the way it is. If I had to answer your question most directly, it is kind of a legacy thing. We have always had a Pain Volume or a Physics Volume that causes damage. In fact, I think you can just take a Physics Volume and have it cause damage if you want. I will be the first to admit I pretty much never use Pain Causing Volumes when I am working. I just used one here because it was kind of handy and nifty. It is cool to know the idea of damage lives in the engine, but the idea of health does not. While that may be a little counterintuitive, it is good knowledge for you to have. If you are wondering, "How do I implement a damage system in my game?" Look into it because you might not have to. Maybe Alexander can highlight the questions I have already addressed, so I don't have to do that. Without any other questions popping in, let's continue. We will address any other questions that come in towards the end of our discussion. This brings us to our next topic, which is Blueprint Interfaces. Blueprint Interfaces are a way we can specify functionality without any kind of implementation. This is just the concept. This is how and why Blueprint Interfaces work. We are going to get into how to actually use Blueprint Interfaces as we move forward. An example of a Blueprint Interface would be when you tell two different people to get their favorite food. Person One says, "My favorite food is homemade pizza. I am going to make my own homemade pizza with all this awesome stuff on it." Person Two says, "My favorite food in the world is Chinese take-out". He gets on the phone, calls up some take-out, and goes to pick it up. These two people did two really different activities, but you gave them both the same command. The nice thing is Blueprint Interfaces don't really care whether or not the receiving object knows about them or knows what to do with them, or if the receiving object is even capable of doing anything with them. Imagine a third person that is a robot and doesn't eat. You tell them, "Go get your favorite food," and they stare at you with their lights blink a couple times because they have no idea what to do with that command. That is okay; your game won't crash. When you know you want to send a signal out to something and you don't really care what that thing does, you just want it to do something, then you probably want to use Blueprint Interfaces. Blueprint Interfaces are still 1-to-1 communication. You are going to get a reference. You are going to send a message to that reference. You could still use loops in order to make the communication 1-to-many. Again, each iteration of that For Each Loop is a 1-to-1 level of communication. Then, the sender is still going to need some reference to the receiver. It is not just a blank signal being tossed out into the world. You have to get that initial reference. That reference is going to drive who you are actually communicating to. Now, how do Blueprint Interfaces work? Blueprint Interfaces are a unique form of communication because they are their own Unreal asset. You will start by making a Blueprint Interface in the Content Browser, which we will demonstrate later. You are going to send data, called a Blueprint Interface Message through that asset and out to any of the listening objects. By default, nothing receives a Blueprint Interface Message. If you build a Blueprint Interface and you send a message out through it, by default nothing will receive what you just sent out. You must implement the Blueprint Interface onto any Blueprints that are intended to receive. Unless you do this, that Blueprint Interface does nothing. Think of a Blueprint Interface kind of like just a piece of wire. You have a switch and you have a light bulb, but you have to have a piece of wire that connects in between the two or nothing is going to happen. The Blueprint Interface is going to be your wire. This means anything that doesn't need to respond to a Blueprint Interface Message simply doesn't have to implement the Blueprint Interface. For example, I have a switch on my desk that I could flip and I don't want it to affect the laptop over on the other desk. That is fine. I don't have to run a wire to the laptop. I can throw the switch all day, and nothing happens over there. If you have objects that don't need to respond to a Blueprint Interface, simply don't implement the Blueprint Interface and everything will be just fine. The nice thing is you can still send signals out through the Blueprint Interface and if nothing implements them, then nothing will happen. It doesn't mean you have any errors. Nothing will crash in your game, and you can keep moving forward. Next, it is perfectly safe to send Blueprint Interface Messages to objects that don't implement the appropriate Blueprint Interface. This is kind of what I just said a moment ago. If you haven't implemented the Blueprint Interface, nothing will happen. It will just silently fail and continue. You should know about this because if you have set up some important behavior between two (2) Blueprints involving a Blueprint Interface and you forgot to implement, then nothing will happen. One of the first things you should double check is if you implemented the Blueprint Interface, and check if you implemented it correctly. Make sure you know those sorts of things. When are you going to use Blueprint Interfaces? When you are sending a signal to some other object and you don't really care what it does once it receives the signal. Or, if you don't even care if the receiver even knows about the signal. The receiver is almost completely unimportant to you right now. You are just going to send something out, and hopefully the thing at the far end knows what to do with it, and responds in-kind. If they don't, then no worries. The message continues on and everybody keeps on playing. If you want to send a signal to an object and they do know what to do with it, then it is just going to work. Here is an example in terms of games. I have an interaction. I am going to press the B button, and then we send out an "InteractWithThings" signal. Doors magically know that they should open. Lights know that they should toggle on and off. Potted plants don't know anything and they don't do anything, so they are not going to care that you are interacting with them. In that case, we would implement the Blueprint Interface on the Door and the Light. We would not implement anything on the Plant, and therefore nothing would happen. The point is whatever happens, whether it is the Light toggling or the Door opening, the implementation is the receiver's problem. As the sender, you don't even care. We are really zoomed in on that PowerPoint. Shelley Collum: I just like "Potted plants don't do anything." Zak Parrish: Oh, okay. We need a highlight right there. A quick, fun fact. Blueprint Interfaces can be used for communication between Sub-Levels. I will show this off really quickly once we get to our actual demonstration. There are lots of people asking about communicating with Level Blueprints. You can totally do it. You are just probably not going to communicate so much with the Persistent Level. As a matter of fact, I will kind of plant this seed in the back of your head. If using Level Blueprint is something you really want, you are going to have a much easier time if you make a Sub-Level. This is the case even if that Sub-Level only exists to hold the Level Blueprint and anything that would need to communicate with said Level Blueprint. Okay, moving along. Blueprint Interfaces in action. Here is a quick practical rundown of how Blueprint Interfaces are going to work. If you are watching the tiny screen in the window, I have some notes to keep me on track. I am making sure my notes are all queued up. You are going to start by creating Blueprint Interfaces in the Content Browser. Right-click in the Content Browser, go to the Blueprint sub-menu and select Blueprint Interface. Then, you give the Blueprint Interface a name and press Enter. In the Blueprint Interface Editor, you will automatically get your first Blueprint Interface function. You have to give the function a name, and then you can start setting up things like inputs and outputs. Once you have done that your next step... As a quick note as you are setting up the inputs and outputs, you will notice that you cannot set up any functionality. As we will see, these are not like regular graphs; you can't add more nodes to them. I am not going to jump away and show you just yet. Then, you will implement the Blueprint Interface on receiving classes. Any class that cares about and has to receive this message, will implement the Blueprint Interface. This is important to note. The way you implement the Blueprint Interface is by going to the Class Settings of the receiving class. Under Implemented Interfaces, add your new Blueprint Interface. It is very, very easy. Make sure you click Compile when you are done. Until you recompile, that Blueprint Interface doesn't exist as far as the Blueprint is concerned. If you try to set up Blueprint communication through Blueprint Interfaces and you haven't recompiled, UE4 is generally pretty good about warning you. Just make sure that you read the warning very carefully. Once you have done that, you can create an event in your graph that is named the same as your function. When this class receives the message for that Blueprint Interface function, something will happen in return. As I said before, note that receivers are the only things that actually need to implement the Blueprint Interface. You don't have to worry about implementation in the sender because anybody can call a Blueprint Interface. Anything in your world can make a call out to a Blueprint Interface. Only receivers have to implement the Blueprint Interface, and therefore respond. As I mentioned in the earlier example, only the Door and the Light would implement the Blueprint Interface. The Plant would not need to implement because it is just going to sit there and keep pumping out oxygen like plants do. Implementing Blueprint Interfaces by way of events. Here is a fun little quirk about Blueprint Interfaces that we will see. I will make sure to show it off. If you make a Blueprint Interface function that has a return value, it is implemented on the receiver as a function. If you make a Blueprint Interface function that has no return value, it is implemented as an event. If that sounds confusing, just hang on and I will show you how this works. Here is a quick visual example. On the left is what the Blueprint Interface Editor would look like when we are creating our Blueprint Interface for the very first time. Notice, we have no return value. In the Details panel, you can see there are Inputs. If we could scroll down, you would see there are no Outputs as well. When we go into the Event Graph to send a call out to that Blueprint Interface, on the right is what it looks like. We are just sending something out. Notice, we have an input. We are sending something out; we are just not worried about getting anything in return. This script fires off like an event. On the right, this is what you actually get on the receiver's side. You get an event that you can implement in your Blueprint. It starts here. This is what the sender sees. This is what the receiver sees. The receiver will get an event that they can tie all sorts of functionality to. Here, the sender is just making a call to the Blueprint Interface Message and sending out a Boolean. Then, our receiver gets that Boolean and does some things. In this case, it is just deciding to print True or False to your screen. The other side is if you are setting up your Blueprint Interface and you have an output value, then this will get implemented as a function and not as an event. If you don't know the difference between events and functions, I will show you the difference. It is possible you will need to do more homework because there is a remedial level of Blueprint knowledge you need to make sure you are very comfortable with before you can make the most of this information. Here it is written out for you. If you have an output, it is going to be a function and not an event. On the right is what you will see on the receiver. On the left is what you will see in the Blueprint Interface Editor. What you will see on the sender is similar to the image on the right, but there will be a Return Value on the lower right hand corner of the node. Then, you will get a function that you will have to set up in some way on the receiver. This slide shows a little bit more of what the Event Graph will look like on the sender. You will call that function. You can send it an input if you like. Then, you will get some sort of an output that you could then do something with. Okay, a bonus trick. You can use a Blueprint Interface for self-calling functionality. Once a Blueprint Interface function has been implemented on the receiver, there is no reason why the receiver can't also use that same Blueprint Interface to send messages to itself. Why would you ever want to do this? If you know that you want to have a certain list of functionality on a set number of classes, and maybe those two objects cannot possible exist in the same class hierarchy; then you could implement the same Blueprint Interface on both of them. You are going to have the same functionality there, you just have to finish the implementation. What is it going to do with the data? The point is anybody can call a Blueprint Interface. It doesn't have to implement it to call it. Even somebody who has implemented the Blueprint Interface can call the Blueprint Interface on itself. Again, it is kind of a way to guarantee that a certain amount of functionality exists on a class. If that doesn't make sense to you, don't worry about it. Just remember that I said it because it will probably come to you on the bus. All right, let's give a demonstration of Blueprint Interfaces. Then, we can go into a few questions about Blueprint Interfaces. Then, we will move on from there. Meanwhile back in UE4 where we left off a little while ago. I might be dying a little bit over here with all the talking. I am going to open my magic bottle of water. Okay. A little bit less death. Let's make a couple of things that we can interact with. We are going to set up a very basic interaction system that leverages Blueprint Interfaces. We will talk to a couple of different things. For starters to set up your basic interaction, we need to expand the functionality of our default Character that comes with this project. Click Edit and select Project Settings. Under Engine, select Inputs. Under Bindings, expand Action Mappings, and click + to add a new Action Mapping. Call this Action Mapping "InteractButton". I normally wouldn't call it Button, but it is going to keep things a little clearer as we move forward. Click the key value drop down menu and set this to the E key. Click + to add another Action Mapping. Call this Action Mapping "QueryData". Click the key value drop down menu and select the F key. Interact with the E key, and QueryData with the F key. These inputs are going to be fairly generic. We will figure out what they do inside of our Character. Next, let's build our Blueprint Interface. Now that we have set up our inputs, we will build a Blueprint Interface. Right-click in the Content Browser, go under Blueprints, and select Blueprint Interface. Call this Blueprint Interface "iInteractable". This is just me, but I like to name my Blueprint Interfaces using adjectives. As I apply them to an object, I can look down the list of implemented Blueprint Interfaces and see this object is interactable, or it is damageable, etc. I have an i at the front as a brief reminder that this is a Blueprint Interface in case I see it listed somewhere and I am wondering what kind of object it is. Double-click to open iInteractable. We open to the Blueprint Interface Editor, which automatically comes in with a function that is just sitting there. In the My Blueprint panel, call the function "Interact". I called the other function InteractButton to alleviate a tiny bit of confusion. For this, we are not going to worry about any kind of input or output. However, we will add another function. Click Add New and select Function. Call this function "GetInteractState". This function will at least have a return value. Select GetInteractState. In the Details panel under Outputs, click New. That will give us a Boolean, which is fine. Name this output, "InteractState". The screen is like a mile and a half away, so I hope it says InteractState. Actually, I can see it just fine. But there is something about using a monitor that far away that just doesn't feel right. We have our Blueprint Interface set up. It has two (2) functions: Interact and GetInteractState. Interact has no output value. GetInteractState does have an output value, but notice the graph is completely greyed out and we cannot do anything with it. We can select nodes, but we can't move them. We can't add new nodes. If you try, UE4 kind of yells at you. I assume bold font is yelling. It says, [in a stern voice] "Cannot create new nodes in read-only graph". I imagine if UE4 had a voice, that is pretty close to what it would sound like. Click Compile and click Save. We are done. We can close iInteractable. We don't really need it. We can close SuperHealingVolume and HealingVolume. We will need ThirdPersonCharacter because that will be what we work on next. We have our Blueprint Interface all set. Now, we need our Character to utilize this information. This is why we set up the inputs at the beginning. Right-click in the graph, type "interact" and select InteractButton, which is our action event. Right-click in the graph, type "data" and select QueryData. There is another action event for that as well. We have these two (2) different Buttons. We need to have some sort of a reference for this. Remember from very early on, I mentioned all Blueprint communication is going to take place by way of a reference. You have to have that reference. That is what we are going to set up now. We are going to set up a very simple trace that will allow us to figure out what object we are trying to interact with. I am going to jump over to this in my notes; not because I don't remember how to do it, but because I want to make sure I set it up the same way as in my notes in case I ever have to hand these notes off to anybody else. I am just covering myself. Here is what we are going to do. Right-click in the graph, type "sphere trace" and select SphereTraceByChannel. What is a trace? Real quickly, a trace is just a line drawn through 3D space which is going to see if it hits anything. It is kind of like firing an instantaneous laser into the world. If that laser hits anything, it is going to feed some data back. This trace is special because it is a sphere trace. It is not going to just shoot a laser, it is going to sweep a sphere through the world instantaneously. Along that sweep distance it will check to see if the sphere hit anything. If so, let's do some things to it. First, we need to figure out where this trace will start and end. Let's get something that has a location in the world. I am going to get a CapsuleComponent. We will get a reference to the Capsule Component. Notice, I just dragged CapsuleComponent in from the Components panel. Drag off Capsule Component, type and select "Get World Location". This will be the beginning of our trace. Plug the Return Value into Start. This is where everything will begin. Drag off Capsule Component, type and select "Get Forward Vector". Basically if you were to make a vector or a line from this Capsule Component, what direction would that line face if it was pointing forward? The same direction the Capsule Component is facing. It gives us that vector, which is pretty fancy when you think about it. Drag off the Get Forward Vector Return Value, type "*", and select vector * float. We are going to multiply this value. If you multiply any vector by a float, you are multiplying all three (3) components of that vector. You are scaling the length of that vector. Set B of the Multiply node to 100. Right-click the B float value, and select Promote to Variable. Call this variable "TraceLength" because that is the length of our trace. Here is a quick shortcut, if you didn't already know this. If you set a value first and then you promote it to a variable, its Default Value will be whatever you had hard-coded. Sometimes setting the value first can save you a few extra clicks. Now that we have all of this, we are going to drag off the Get World Location Return Value, type "+" and select vector + vector. Plug the Multiply node Return Value into the vector + vector node. Plug the Add node Return Value into End. What does this actually mean? All of these nodes are simply saying I want you to sweep a sphere 100 units forward from our Character's Capsule Component. That is it. That is all we are doing. It is actually very basic. Then, let's give this sphere a radius. Set Radius to 50. If you want to be hard-core, Right-click Radius and select Promote to Variable. Call this variable "TraceRadius". Cool. We have that, and it is all good. It is done. Now, we need to do some things with whatever it is we hit. The Out Hit is how we get our reference. This Out Hit output is a struct. A struct is just a culmination of a whole lot of data. A struct is like a bucket full of different kinds of data. If you Right-click Out Hit, you can select Split Struct Pin and you will see all these different pins. One of these pins is the Out Hit Hit Actor. [Laughing] That is the Out Hit Hit Actor. This is the Actor we actually struck with our trace. We could do this in a few different ways. We could just call our Blueprint Interface Message on this. In fact, note we have done nothing with our Blueprint Interface on the Character itself. There has been no implementation, nor discussion of implementation. Drag off Out Hit Hit Actor and type "interact". Check it out. Under Class iInteractable, you will see Interact (Message). The Blueprint Interface Message is how we send that out. That is how that works. We could just select Interact (Message), but I am going to take it one step further. We don't know if this trace ever actually hit anything. It would be nice not to call this message if it turns out the trace hit nothing. Drag off Out Hit Hit Actor, and type "is valid". You will see two (2) options: an Is Valid function, and ? IsValid. You don't see the second very often. Select ? IsValid. This is kind of like a quick branch statement. Plug SphereTraceByChannel into the IsValid Exec. It is saying to take an incoming object. If it is valid, which means it didn't come up as null and it actually hit something, then we want to call Interact on whatever that object was. We sent that out by way of a Blueprint Interface Message. Then finally, plug Pressed into the SphereTraceByChannel. That is it. I am going to try my best to give you a nice full-screen view of that. If you really want to, you could take a screenshot of this and save it somewhere. There you go. That is all we are doing right there. That is the whole kit and the whole caboodle. We are not going to bother testing that right now. We can't actually test right now. The only thing we can do is set the Draw Debug Type to For Duration on the SphereTraceByChannel. Click Compile. Go to ThirdPersonExampleMap and click Play. Press E, and you can just barely see it. I don't know how well the capsule shows up on the camera. You can see a little capsule that appears in front of our character. However the character turns, the trace always shoots out from the forward direction. If I press E over and over again, the trace gets darker so it is a little easier to see. If that trace hits something, you will get a little green version of the capsule, like so. Cool. The trace is working, but right now we have nothing with which to interact. Now, let's focus on that next. I tell you what, let me redact that really quick. We have already implemented the InteractButton. Let's also take a minute and set up how QueryData is going to work. As a quick reminder because I have been talking for a minute, Double-click to open the iInteractable Blueprint Interface. In the My Blueprint panel, we have our Interact function and our GetInteractState function that has a return value. Go to ThirdPersonCharacter. Let's make sure the ThirdPersonCharacter is ready to do something with both functions. Here is the deal; this is going to work in very much the same way. We are going to send out some kind of trace, but we are going to call a different Blueprint Interface Message. If you ever find yourself re-using script, it is very easy to press Ctrl + C to Copy and press Ctrl + V to Paste the script. Most of the work is already done and I don't have to create it over and over again. Great! Awesome! No, that is perfect. You did a great job just then. The problem is what if you decided you wanted a different kind of trace? What if you wanted a capsule trace, or a box trace, or something else entirely? Then what do you do? You have to fix the SphereTraceByChannel nodes, and that gets to be a little bit of a headache. I don't want to do that much work. You probably don't want to do that much work either. Be lazy when you can be lazy. Instead, select everything besides InputAction Interact Button and Interact (Message). Right-click on the selected nodes, and select Collapse to Macro. As you may have heard me yell in other training videos, you have some options here. We can select Collapse Nodes, Collapse to Function, or Collapse to Macro. If we Collapse Nodes, we have to Copy/Paste it and each copy is its own individual collection of those nodes. That is not useful because it still means we have to fix all of the different copies if we break something. Making it a function would pretty much be valid and it would work, but try to reserve a function for only the times where external objects need to call and reference that functionality. Basically, is there another object living in the world that needs to call this trace? If so, consider a function. If not, consider a macro. A macro is a way to collapse all those nodes down to a single node. Then you can Copy and Paste that node as many times as you want. If you need to fix something, then you can jump into any copy, fix it, and it automatically fixes it everywhere else. You get the opportunity to be lazy and still get a good day's work done. It is also called being efficient, so don't over iterate on being lazy. Select Collapse to Macro. Call this macro "TraceForInteraction". That sounds like a really useful name. Now, our graph looks really cool, but it has these mind-numbing crossed wires. I don't really have any sort of OCD problem with that, but I am going to fix it anyway. You all have my back on that one. Double-click the TraceForInteraction macro to step down inside of it. Click on the output or input node. In the Details panel, you will see all of the outputs and inputs listed. Expand Outputs and you will an up arrow and a down arrow. Click up and that reorders the outputs. Now, IsValid is on the top and Out Hit Hit Actor is on the bottom. Click Compile and go to the Event Graph. [Sighs] Now things aren't tangled. Our graph looks very neat, nice and tidy. If your friends open your Blueprint and ask how you did so magic in one (1) little node, you can feel fancy. The other nice thing is in order to set up QueryData, here is all we have to do. Select the TraceForInteraction node, press Ctrl + C to Copy, and Ctrl + V to Paste it. Plug Pressed into TraceForInteraction. Then drag a wire off Out Hit Hit Actor, type and select "QueryData". What did I call that? I am pretty sure I called it QueryData. No, I called it GetInteractState. [Laughing] Oh well, that is fine. Drag off Out Hit Hit Actor, type "get interact" and select Get Interact State (Message). There we go. That is just going to work. Plug Out Hit Hit Actor into Target. It also gives us a return value. Drag off the Get Interact State output, type and select "Print String". I am doing this under the assumption that you want to do something with this data. Connect Interact State into In String. UE4 will convert the Boolean to text for us, so we have less work to do. There we go; we are done. We have done the implementation of our Blueprint Interface from the sender's side. Notice, that only required making calls to the Blueprint Interface Messages. They have the little envelope icon on them just to show they are Blueprint Interface Messages. You are sending a nice packet out to somebody. Click Compile. Cool. Done. Awesome. I know time is just ticking on by. I warned you this would be a little bit of a long discussion. Let's build some things we can interact with. Once again, I am just referring to my notes so I do this in a way that can be reproduced later. Let's begin by making a very simple Door. I am totally going to cheat. I know there were some people earlier today on the forums who were asking how to make a Door that opens both ways like a saloon Door or something. No, I am going to cheat and it is going to just slide straight up in the air. Right-click in the Content Browser, and select Blueprint Class. Select Actor. Call this class "InteractiveDoor". Double-click to open InteractiveDoor. Awesome. Here is how we implement the Blueprint Interface. This is going to be a receiving object. In terms of our communication, we have the sender which is going to be the Character; now we need a receiver. Receivers always have to implement the actual Blueprint Interface. Implementation is done in Class Settings. In the toolbar, click Class Settings. In the Details panel under Implemented Interfaces, click Add and select iInteractable. There you go. Before this will work or do anything, you must compile. You must compile! I have to drill that in for some people. Click Compile. Go over to the Event Graph. Remember, one of our functions was called Interact. You might try to go to the Event Graph, Right-click and type "interact" to make an event out of Interact. You select Call Function Interact. You are thinking that is not what I want because that is not an event. You will start getting confused and frustrated. Click Compile. Right-click and type "interact" again. You will see there is a new option for adding Event Interact. When you are trying to set up a Blueprint Interface, you have created a function and you don't have the event when you Right-click, please click Compile before you go to the forums. It will spare you what I am sure would happen, but shouldn't happen. We have a really good community. Somebody might point it out to you. We have our Event Interact here. Now, what happens in response to this event? Something else happened, and it was very subtle. Nobody noticed it. Or you might have noticed it and if you did, good for you. Take a look over in the My Blueprint panel. Under Interfaces, you will see there is now a function called Get Interact State. This function magically appeared the moment we added our Blueprint Interface. Now, that function is there and waiting for us. In fact, let's take a minute to go ahead and implement that Blueprint Interface. It will just take a moment. Double-click to open GetInteractState. Look, we have a function! The difference between this and the Blueprint Interface is now we can start adding nodes, and make things happen. We have this property called InteractState that is just a Boolean. I am totally going to cheat. Right-click Interact State and select Promote to Variable. Call this variable "InteractState". InteractState is going to report this out into the world so we can make use of it later. With that out of the way, let's go back over to the Event Graph. What happens on Interact? This event means we just received a message from some sender. Somebody just called Interact on us. The only reason we had Interact was because we implemented this Blueprint Interface. Again, the Blueprint Interface was like our wire. Now, let's cause something to happen. I don't know what. It doesn't really matter what. We are just going to make it happen anyway. Let's see. I want to make sure I am following along with my notes. First, we need a door in here. Go to the Viewport and let's build something. Begin by clicking the Add Component button, and select Cube. I am going to scale this and make it into a door. Press R to use the Scale tool and scale the Cube in the X and Y axes. Basically, I am making a big plank that will block off the player. I am going to add something on top of this just for functionality sake. You don't always have to do this, but you should know about this kind of thing. It will help you. If you press the E key, that sends a sphere trace out into the world. We built this Capsule Component and we are interacting with anything that hits it. Awesome. Imagine walking up to this Door and you press the button, and it creates your Capsule Component. The Capsule Component hits the Door and everybody is happy. Now the Door knows it is time to open, so the Door opens and slides way up into outer space. It is open, now how do you close it again? Your Capsule Component just goes forward and it can't reach the Door that is sitting way up in the world. We are going to make another invisible object that will handle those interactions when the Door is slid completely out of the way. Click Add Component, type and select "Box Collision". Press R to use the Scale tool and scale the Box Collision roughly to the size of the Door. It doesn't have to be perfect. In fact, it doesn't even have to be particularly close to that size. Wow, I scaled that up crazy high. Let's set the Scale to 1 for X, Y, and Z. Then, I will use the Scale tool to do some scaling by hand. I will thin it out a bit here, and I will make it reasonably tall. Again, it does not have to match up exactly with our Door. It looks like I got it pretty close to being exact anyway, and that is also fine. The important thing we are going to do is the part that will throw a lot of people off. We are going to adjust its collision so the only thing that is going to hit it, in terms of our game, is just that trace. How do we do that? Go back to ThirdPersonCharacter for just a minute. Remember the TraceForInteraction macro we built earlier? Double-click TraceForInteraction to go inside the macro. Remember, we had the SphereTraceByChannel node. That is going to trace along what channel? It is tracing along the Visibility channel. Go to InteractiveDoor. In the Details panel under Collision, click the Collision Presets drop down menu and select Custom. If we want to, we can tell this object to ignore all collisions except trace responses for visibility. Those will overlap, or those will block. That is it. Now, this Door will ignore basically everything except the trace we set up for interaction. That is a very neat trick, and you should make sure to add that to your bucket of tricks. Okay, cool. We have that and we can now interact with our Door. Now, we need to set up a way to get our Door to move from one location to the next. There are a lot of different ways to do this. The way I am about to do it is not even necessarily the "best" way. It is just a way I use a lot, especially for demonstrations and especially when I am prototyping something when I don't know how it will move at first. In the My Blueprint panel under Variables, click +Variable and call this variable "StartLocation". Click the Variable Type drop down menu and select Vector. Click Compile and click Save. Next, select the actual Door. In the Components panel select the Cube, press F2 to rename it and type "Door". Let's grab the location of the Door. Right now in the Details panel, you will notice it has a unique Location because I moved it up into the air. Right-click Location and select Copy. In the My Blueprint panel, select the StartLocation variable. In the Details panel under Default Value, Right-click Start Location and select Paste. That will paste in all three (3) of those values. If you didn't know you could do that, and I am often surprised by how many people didn't know you could do that, that is also a handy trick to have. Next, click +Variable in the My Blueprint panel. Call this variable, "EndLocation". Click Compile. We are going to do something a little fancy for the End Location. In the Details panel under Default Value, set the End Location Z value to 300. That is just a guess. In the Details panel under Variable, click the Editable and Show 3D Widget checkboxes. Make sure those checkboxes are active. Then, click Compile. Go to ThirdPersonExampleMap. Drag InteractiveDoor into the world. You will get a little diamond object you can move in order to update the location of that vector, which is pretty handy. Right now, this isn't going to do anything. Since it is here and we have already added the InteractiveDoor, I am going to put it in front of the stairs. It is kind of Door-like and is blocking off the stairs. It doesn't have to be perfect; this is all for testing purposes anyway. Go back into the InteractiveDoor and go to the Event Graph. What has happened? As far as the InteractiveDoor is concerned, somebody called Interact on us and we want something to happen that we don't even know what it is. What is that going to be? Well, let's make a timeline. Timelines are great for animating objects inside of Blueprints. Right-click, type "timeline" and select Add Timeline... Call this timeline "DoorTimeline". Double-click to open DoorTimeline. Click the button to Add Float Track inside the timeline. Hold the Shift key and click on the timeline twice. It does not matter where you click or what you get out of it because you are going to have to edit it anyway. Hold Shift + Click to select the first keyframe you created. Set the Time to 0. Set its Value to 0. That has already been done. Select the second keyframe. Set the Time to anything you want. I will set it to 0.75 seconds so it is a fairly fast Door. Set the Value to 1.0. We are going to frame that up. Click Zoom to Fit Vertical or Zoom to Fit Horizontal to frame this into view. I will zoom out so you can see the curve that is defined here. Drag a selection box around both keyframes. Right-click and select Auto to make them auto curves, so they get a little bit of curvature, and accelerate and decelerate as the Door opens. Okay, wicked. That was fun. We are done with the timeline. Go back to the Event Graph. Now, we are not going to just plug Event Interact into Play or Play from Start. Spoiler alert: if we do that, then we would have a Door that opened but never closed. We are going to do a slightly different implementation that will allow us to also close the Door. Let's talk about the motion of the Door. The motion of the Door is fairly easy to set up. Notice on our DoorTimeline node, we have New Track 0. That is because I didn't name the curve. Double-click to open DoorTimer so we can fix that problem. Right-click on the curve NewTrack_0, and select Rename. Call this curve "DoorInterpolation". That is a long name for that curve, but it makes sense. It makes me happy. Now, we have a Door Interpolation wire. Drag a wire off Door Interpolation, type and select the "Lerp" node. Lerp is short for linear interpolation. This is automatically going to plug the wire into A. We are not going to leave it in A. Hold Ctrl and plug the wire into Alpha. That is terrible. That is not what I wanted at all. Ignore me. We are going to do a new lerp. Right-click, type "Lerp", and select Lerp (vector). That is what we really wanted. Plug Door Interpolation into Alpha. We are going to interpolate between two (2) different vectors, or two (2) points in 3D space. What are those points? You guessed it. Drag StartLocation onto A. Drag EndLocation onto B. That is it. That is all we have to do. As this plays forward, it is going to output some blend in between those two (2) locations. Next, we need to feed this information to our Door. From the Components panel, Drag the Door mesh into the graph. Drag off Door, type and select "SetRelativeLocation". Choose SetRelativeLocation because those vector variables are in relative space. Plug Update into SetRelativeLocation. As the timeline updates, we will set our relative location to some blend between the start and end points. Plug the Lerp (vector) Return Value into New Location. That is pretty cool and should work, unless I broke something. That only happens 5-52 times a day. Now, we have our Event Interact. Where do we go from here? Earlier, we set up the variable InteractState. This is a Boolean, so it will be true or false. We are going to make an assumption here. When someone has interacted with the Door, it will be open and therefore the InteractState will be set to True. When the Door is closed, nobody has interacted with it and therefore we will set InteractState to False. Knowing that, we can leverage this. Hold Ctrl + Drag InteractState into the graph to get a reference to it. We are going to create a Branch node. You can always drag a wire out, type and select "Branch". Or you can hold B + Click, so UE4 will create a Branch node for you. Plug Interact State into the Condition. Plug Event Interact into the Branch. If Interact State was True, then what do we do? That means somebody has opened the Door. We want to do two (2) things. First, we want to set InteractState back to False. Drag InteractState into the graph. Plug True into Set Interact State. We want to reset Interact State. If Interact State was False, then we want to set Interact State to true. Drag InteractState into the graph. Plug False into Set Interact State. We are just flipping that value. By the way, you can do that in one (1) node, but you are still going to have to split it up in order to operate your timeline. We are not going to dig into all of that. That can be one of those fun little challenges, then you will see why I did it this way. Now, we have that. If Interact State is False, we are going to set it to true. If Interact State is True, we are going to set it to false. Think about this for a minute. If Interact State was False, then we are going to set it to true, and then we need to open the Door. The state was False, which means the Door was closed. Plug the False Set Interact State node into Play. Then if Interact State is True, that means the Door was open and now we need to close it. Plug the True Set Interact State into Reverse. That is it. That should be all we have to do. Click Compile and click Save. Go to ThirdPersonExampleMap and press Ctrl + Shift + S to Save All. Click Play. This is the moment of truth. Walk up to the Door and press E. The Door opens. I can't quite run into it because I think it is too low. Press Esc. Select the EndLocation diamond and drag it higher into the air. Click Play to test again. Press E and the Door gets out of our way. Everything just works. This is a really good argument for using those editable variables. What is also nice is you can select EndLocation, and in the Details panel and set X, Y, and Z to 0. Then, you could decide you really wanted the Door to slide out of the way. I want the Door to move side-to-side and not up and down. Press E and the Door slides. The diamond denotes the center point of the Door. You have to figure out about where the middle is. I will eyeball it and try again. You see the Door kind of slides over. Here is the other part of this. I need to do a couple of things to make what happened very apparent. First, select the Box in the Components panel. In the Details panel under Rendering, uncheck the Hidden in Game checkbox to turn that off. Double-click to open DoorTimeline. I am also going to check Use Last Keyframe so we are not playing a lot of other animations we don't need. Click Compile and click Save. Now when I click Play, you can still see that Box sitting there. I press E and it moves, but I have to hold the camera still because temporal anti-aliasing is a thing. You can still see that Box sitting there. That Box is sitting and waiting for us to interact once again. If I press E again, it reads it, and closes the Door back. Now, I have an interacting Door. We can come over to this Static Mesh which is not interactable. This Static Mesh is not something I ever need to interact with. I can press E, and nothing happens. This kind of drives home the point of Blueprint Interface communication. If you have the Blueprint Interface implemented, something can happen. If you don't have the Blueprint Interface implemented, nothing happens but it doesn't matter. You are still going to be playing your game. We also implemented the F key, which is going to return our Interact State value from our function. As a quick reminder, here is how that worked. Go back to InteractiveDoor for just a moment. Take a look at Get Interact State. It is getting the Interact State Boolean and firing it out into the world. Go to ThirdPersonCharacter. When we call Get Interact State, it is getting Interact State and printing it to the screen. Click Compile. Go to ThirdPersonExampleMap. Let's test it. Click Play. Run up to the Door and press the F key. We should get false printed to the screen because nobody has interacted with the Door. We do get false. Press E to open the Door. Press F, and now it is true. You have seen how Blueprint Interfaces can be implemented as an event and as a function, albeit in a pretty basic way. There is one more thing I wanted to throw out for anybody who wanted to do it. This example is very academic, but it is also very important for you to know about. The example is how to use Blueprint Interfaces as a way to handle Level Blueprint communication. A quick spoiler alert: you are not going to easily be able to communicate with the Persistent Level. Communicating with the level that exists when you first start building a map can be done, but it is not the easiest thing in the world. If you know you are going to want to use the Level Blueprint and you know you are going to have a lot of cross-talk via that Level Blueprint and other things, then you want to have a Sub-Level. That Sub-Level will need to hold the Level Blueprint you wanted to build. If there are any Blueprint objects that need to talk to that level script, then make sure they are in that Sub-Level as well. Remember that I said that because this example is going to be a little bit on the academic side. Press Esc. We will show this off. Click Window and select Levels. I generally always dock this window behind the World Outliner. It makes me happy, so that is where I am going to put it. Click the Levels drop down menu and select Create New... Call this level "ScriptSubLevel". It is a boring name but it tells what it does, which is great. Next, it is very important to Right-click on ScriptSubLevel, go to Change Streaming Level, and select Always Loaded. We are not going to worry about streaming this in and out. It is important to note if you try to communicate with the level that is not streamed in, you will get problems and you won't get expected behavior. If you are going to have a level that is just for Blueprint communication, then make sure the level is always streamed in. If you have to stream the level out for some reason, just know to only talk to the level when you have streamed it in. Once we have that, here is the cool thing you may not have already known. In the toolbar, click the Blueprints button, go to Sub-Levels, and you will now see Edit ScriptSubLevel. Select Edit ScriptSubLevel to edit the Blueprint. Here is the fun thing. Now when you click Class Settings there is a section for Implemented Interfaces in the Details panel. You can implement Blueprint Interfaces on Sub-Level Blueprints. You can't implement Blueprint Interfaces on the Persistent Level; I am really sorry. But you can implement Blueprint Interfaces here which is a pretty good consolation prize. It is not the new Corvette, but it is a pretty good Mustang. Under Interfaces, click Add and select iInteractable to implement it. That is pretty much all we have to do. We now have access, if we want. I would have to break the Door or break something to make this happen. Let me break the QueryData function I have assigned to the F key. Right-click in the graph. As soon as I did that, you will notice in the My Blueprint panel under Interfaces, we have GetInteractState. Double-click GetInteractState. We can just set this to something. Let's make a variable here inside of the Level Blueprint. Click +Variable and call this variable "InteractState". Drag Interact State onto Interact State. Again, I am going to keep this very academic. Click Compile. In the Details panel under Default Value, check the Interact State checkbox to hard-code this to true. Click Compile. We are going to reach up from the Character, and get this piece of information. I want to show you how that works. I am going to hold Alt + Click to disconnect the wire from QueryData. I am going to completely disconnect the InputAction QueryData because we are going to do something mostly different. You can Righ-click on any Blueprint, type and select "Get Streaming Level". Get Streaming Level only works with Sub-Level Blueprints. Is not going to work with the Persistent Level. That is how this is. It is just what you have to deal with. Package Name is the level name. What did I name that level? I named it ScriptSubLevel. Type it out just like that. Set Package Name to ScriptSubLevel and press Enter. Basically what you are doing is telling this to get a reference to that Sub-Level Blueprint by name. With that, we can just send it a message. Drag off Return Value, type and select "Get Interact State". We are just sending it a message that has a return value. Plug Pressed into Get Interact State. We are expecting the return value to be true because we hard-coded it. Actually, let me select Get Interact State and press Delete. I desperately want for there to be no confusion. I am going to go back over to iInteractable. In the My Blueprint panel, click +Function to add a new function. Call this function "LevelComm". It is short for level communication. In the Details panel under Outputs, click New. Click the output type drop down menu and select String. Call this output "LevelString". I am only doing this to make this a little bit clearer. Click Compile. I feel like if I overuse the same functions, somebody might be wondering, "How did he do that?" I don't want that to happen. Go to ScriptSubLevel. In the My Blueprint panel, you will notice LevelComm is here as well. We can re-implement Level Comm. Let's hard code Level String to "You have successfully communicated with the sub level!" That is a long message, but that is fine. Click Compile. Go to ThirdPersonCharacter. Now, we get a reference to our level by name. Let's send it that particular function we called LevelComm. Drag a wire out from Return Value, type and select "Level Comm". We don't have to worry about casting because we don't care if this has the Blueprint Interface or not. If it has the Blueprint Interface, it will do something. If it doesn't have the Blueprint Interface, it will do nothing and we don't care. Drag off Level String, type and select "Print String". Done. Cool. Click Compile and click Save. You are getting a warning that says, "'ReturnValue' is already a 'LevelStreaming', you don't need LevelComm". What it is telling me is that functionality is already there. Drag off Return Value and type "LevelComm". Oh, I see what it is saying. I am not going to stress on that too hard. Click Compile. Let's move forward. I don't even necessarily think UE4 should be telling me that right now. I will go to ScriptSubLevel and click Compile. I will test it. I am going to click Play, and press F. "You have successfully communicated with the sub level!" From an academic perspective, it is possible UE4 should be telling me that message. I don't think you should be too worried about that warning. The Return Value from Get Streaming Level is already Level Streaming, so it is saying we don't need to be using iInteractable. I think we do because we have to send that through the Blueprint Interface. Again, I am not going to reiterate that. The point is that it works. The point is we just did something that communicated directly with a Sub-Level, and that allowed us to use Level script for those times we need to communicate. When you need to communicate with Level script, consider keeping all your Level script in a Sub-Level specifically for that purpose. "You can always reach out and touch someone", which is a really old slogan. With that, let's jump over and take a look at some questions. Some of these questions will be better answered at the end, which is fine. Is it best practice to create Health as a Blueprint Component? There are so many ways to implement Health. Let's talk about that at the end. I am looking for questions specifically about Blueprint Interfaces. I guess that question was about Blueprint Interfaces, wasn't it? Is it best practice to create Health as a Blueprint Component and use Blueprint Interfaces rather than Direct Blueprint Communication for every Actor that has Health? It really depends. If you had a Parent Class that was called something like Living Object and all of your things that have Health inherit from that class, then everybody immediately has Health and you don't really need to have a Blueprint Interface. You could do it. You could add a Blueprint Component. I try to advise people against getting too heavy with components. It is a development path that we have not tested very heavily at Epic. As you might have seen, you can make Blueprint Components. I have done some training videos about Blueprint Components. I think they are the bee's knees and are very cool. For example, say you have 40 different things your object can do so you make a component for each one. Now, you have this object with 40 different components. Now spawning that object in is significantly slower, than if it didn't have all those components. Be cognizant of things like that. To me, a Health property is something that would be common throughout all objects of a similar type. Anything that needs to have Health is going to have it. I would have a Parent Class that has Health and go from there. That is going to be much easier than trying to add the same component to everybody. You could go either way because component based programming is what it is. If I want a function to affect multiple enemies in a game, would it be better to create a Blueprint Interface function? Or, to put them in an array and make a For Each Loop, and then loop each node? It depends on so many things. One of the ways you could do that is with an Event Dispatcher, which we will talk about next. Let's say what you are talking about is like an AOE (area of effect) attack. That is the first thing that comes to mind. I hit a button and this big ring-wave of fire casts out from me, and it looks amazing. Then, everybody who is nearby gets hurt by it. We will talk about Event Dispatchers in a minute. If you don't get this, that is fine. Just sit on it. The moment your spell goes out and hits everybody, all that does is passes a reference to everybody. It says, "Hey I'm about to do something, so here is a reference to me." Then, everybody can start listening out for the effect. You could really go in so many different directions with this. Neither of the things you said are necessarily wrong. I guess if I had to do it either way, I would probably do both. You said either or. Would it be better to create a Blueprint Interface function or to put them in an array and make a For-Each Loop node? The answer is probably both. You are going to get an array of everybody you just hit with your AOE, and then you are going to call that Blueprint Interface function on all of them. Then, only the "enemies" who had the Blueprint Interface implemented are going to be affected by it. Anything nearby like a chair, or a piece of shrapnel, or something sitting on the ground that doesn't need to be affected won't have the Blueprint Interface and won't be affected. Your game will just continue on. The answer is yes to your either or question. I love those types of questions. Maybe this was already answered, but does having many Event Dispatchers actually slow the game down? It depends. It shouldn't be significantly slower. I imagine if you went to a really high digit number in multiple factors of 10, that could slow things down. As always, your best option in those cases is to start profiling. See how much CPU you are using by calculating all of this data. With that, let's go back to our mighty PowerPoint presentation. Let's talk about our final topic for the day. We are a little over where I wanted to be. I am sorry for carrying on a little bit long. I am going to take just a second to rehydrate. We are going to talk about Event Dispatchers. Event Dispatchers are kind of different. Event Dispatchers freak some people out, and they shouldn't. I find a lot of people are not comfortable with Event Dispatchers because I think there might be a little inadvertent mystery around them. Hopefully, today we will help get rid of that. What are Event Dispatchers? First, Event Dispatchers are a way to establish a listening type relationship so that the receiver is listening for an event to take place on the sender. Then, the receiver can respond however it likes. Previously in both Direct Blueprint Communication and in Blueprint Interfaces, we have a sender that actually does something. The sender makes the Blueprint Interface call. The sender grabs a reference and says, "Hey you, I am going to do this thing to you. I am going to send you some data from you, I am going to call some data, and then I am going to call some functionality". The sender is doing something. Now, the sender will say, "Hey, whatever. I am doing something. Anybody who cares about it should respond." Event Dispatchers are like Twitter in a lot of ways. That is probably the best analogy. If you are every confused about how Event Dispatchers work, keep Twitter in mind. The way it works is you will set up an Event Dispatcher on the sending object. This is exactly like setting up your Twitter account for the first time when you go to Twitter and create your username, etc. Any number of receivers can then bind to your Event Dispatcher. This is just like people following your Twitter feed. Whenever you send out a Tweet, these are the people who will be listening. They are the ones who will actually receive your message. Keep in mind from the UE4 side, the receiver will need a reference to the sender. This is why Event Dispatchers are different than the other communication methods. Up to now, the sender gets the reference and the sender makes the call. Now, the sender isn't even going to bother with a reference; it is just going to make the call. The receivers will get a reference to the sender and say, "Hey, let me know when he makes a call to this one (1) thing." Or to continue with our analogy, "Let me know when he makes a Tweet". Next, the sender will call the Event Dispatcher. This is exactly like making a Tweet, which is just sent out into the ether. By the way, this is the closest thing we have to that widespread broadcast approach to communication that a lot of people ask for. The sender will send this out to anybody who might be listening. It could be that nobody is following the sender. It could be that nobody has an Event Bound to that Event Dispatcher, in which case nothing happens. For example, this is a lot like when Chance makes a Tweet. Nobody loves it and nobody responds, and Chance comes to me crying. That kind of thing happens from time to time. It means that Tweet happened, and nothing happened in response. The followers didn't care, or maybe at that point there were no followers. It is okay, Chance. However, if there were followers and maybe this time Chance actually said something interesting, then they will say, "Oh, Chance just said something cool. Let's go Tweet about it. Let's go get on Facebook. Or, let's go to the webpage he was talking about.", and then Chance is happy. The moral of the story is be nice when Chance Tweets. Say something good to him; he needs that. Lastly, any of the receivers who had an Event Bound to the Event Dispatcher can then react accordingly, which is kind of what we were talking about. Let's continue with our slide deck before we move on. When do you use Event Dispatchers? How do you known when an Event Dispatcher is the right method? When you have an event on the sender that you know needs to be sent out to a lot of different things and each of those things could be doing their own behavior in response. Maybe you have a boss character in your level that is a great big toad-looking boss character. The moment he dies you want the walls behind him to crumble to the ground, you want the torches that were surrounding him to all go out, and you want music to start playing, and you want the character that looks a lot like Chance to do a victory dance. You want all of that. In that case, you would have something that was sent out the moment the boss died. All of the level elements like the torches, the walls, etc. would be receivers, and would respond however they were supposed to respond. When you know who or what the sending object is going to be, and you know you are going to be sending something out and things are going to have to respond to it no matter how many receivers there are, then it is probably time to use Event Dispatchers. You need to make sure all of the receiving objects can somehow get a reference or know about the reference in some way. Again as an example, that is how they tie into that Twitter feed. Then, the receivers are also going to have to know when to start listening for specific events, and possibly when to stop listening. For example, if you wanted to as a challenge, think about this. Once we have talked about Event Dispatchers, how could you implement an Event Dispatcher as a form of interaction? For example, you could set it up when you walk up to a Door, the Door starts listening out for you to interact with it. You press your Interact button and the Door recognizes that you came into location and opens the Door. When you walk away, we need to know to stop listening so the next time you press the E key from across the room, the Door doesn't close from really far away. The receivers potentially know when to stop listening as well. There may be some Event Dispatchers which will run the entire course of the game. The Event Dispatcher we are going to set up is going to run indefinitely. Just know as you can bind objects, you can also unbind them so you stop that relationship. Next, Event Dispatchers in action. Event Dispatchers are a little more like classic functions or even variables in Blueprint. You are going to create Event Dispatchers in the My Blueprint panel of the sending Blueprint, not in the receiving Blueprint. The receiver doesn't care. If you have to pass along any data like current Health, which is what we are going to be doing, then that data will become an input. We will discuss signatures for your Event Dispatchers in just a moment. Don't even worry about that word is; we will come back around to it. An Event Dispatcher cannot have an output. That would defeat the purpose. The purpose of an Event Dispatcher is just sending out data, and you do not care what happens with it. Nothing might happen to it. It doesn't matter; you are just sending it out. You don't care about return values because of that. Nothing might happen, and that shouldn't change anything. At some point in your Event Graph, your sender is going to have to call this Event Dispatcher. Call is a specific word you are going to be using. Call this specific Event Dispatcher. To do that, Drag a reference to the Event Dispatcher into the Event Graph, and choose Call. We will talk about it and you will see that in action in a few minutes. In the receiver class, you must have a reference to the sender first. It is your responsibility to get that reference to the sender. Again just as a reminder, this is why Event Dispatchers are different than the other two (2) types of communication. This time it is the receiving class that gets the reference, and not the sending class that gets the reference. Once you have that reference and you have confirmed it is the class you want (probably by way of casting), then you can bind an event to the Event Dispatcher by name. You can create a Custom Event that will connect to the event pin. Then whatever you plug into that Custom Event, will be what executes. Again if that doesn't make sense, don't worry because you are about to see it in a couple of minutes. Then you will be like, "Oh, now I know what he was talking about". Just know the receiver class may need to stop listening at some point. Stop listening means just unbinding the event. We are going to explore unbinding events, but we are not going to practice this because we are going to create a quick HUD. We will use Event Dispatchers to transmit data to a HUD, which as a quick note, is a very efficient way to handle that. If no objects have made a bind to an Event Dispatcher, then nothing happens. That is simply it. Nothing will happen in response, and this is perfectly safe. It is totally fine. When you are setting up Event Dispatchers for the first time, you can set up the first Event Dispatcher for your sender, and then know you can tie things into it later on. That may come tomorrow or late in your game design; you know it is there and you could hook things up to it if you wanted. Next, Event Dispatchers on the sender and kind of what they look like. From the sender's perspective, you only need to set up the Event Dispatcher and then call it at some point in the Event Graph. That is it and that is all there is to it. This is generally going to be in response to something important that you care about because it is a lot like calling a function. Notice that the call itself does not require a reference. I keep emphasizing that. The sender doesn't have a reference, and that is how this form of communication works. Event Dispatchers on the receiver are a little bit different. Any object wanting to receive an Event Dispatcher must have or somehow obtain a reference to the sending object. It must bind it own Custom Event to that Event Dispatcher. This Custom Event must have the same signature as the Event Dispatcher. Again, we will talk about signatures here in just a second. Once the bind is complete, then the system just sits and waits. Again, that is just like following somebody on Twitter. Right after you get your mobile device you say, "Oh yeah, Chance is awesome. I am going to follow him on Twitter." Then, what do you do? You wait. I imagine this is what Chance expects. He imagines everybody is just waiting patiently for him to text, and they are just staring at their phones the whole time. In a way, that is what you do. You just sit there and wait for him to make a Tweet. Then as soon as he does, you see it and you can respond. That is exactly how Event Dispatchers work. First, you make the bind. Then, you are following the Event Dispatcher, and then you wait. The moment that Event Dispatcher is called, then the script connected to the event will fire. That is what that little red line is for. If you haven't played with Event Dispatchers, you may be wondering, [high pitched voice] "What is the little Event wire for?" Now you know. Event Dispatcher signatures. A signature is just the combination of different inputs that an Event Dispatcher can have. Signatures are specific to each individual Event Dispatcher. Signatures can be shared. If you have different Event Dispatchers which need to be sending the same data, you can share their signatures. There is a Copy Signature drop down menu where you can select to share a signature when you are creating an Event Dispatcher. I tend not to use the drop down menu that much, but it is there. Then, signatures are really the way you make Event Dispatchers intelligent. You can test the input data, and do different things on what you find. We are going to be using an Event Dispatcher to send an amount of Health up to a UI. Your UI could be smart and say, "Hey, did the amount of Health just drop down below a certain level? If it did, then let's change the color of the Health bar from green to red in response." That lets you know you are low on Health. UE4 does most of the work for managing signatures. If you are using a really old version of UE4, which I think means 4.5 and earlier but I could be completely wrong. I know it was a long time ago that you had to handle a lot of the signature setup yourself. Now, you don't really don't have to worry about it so much. In fact, I am only mentioning it here just so you know it exists. For the most part, you don't have to stress about signatures. Next, Event Dispatcher options. When you drag an Event Dispatcher into the Event Graph or when you Right-click and try to access Event Dispatchers from inside the receiver, you are going to see a lot of options. You should know what all the options mean. You will see: Call, Bind, Unbind, Unbind all, Event, and Assign. Call is going to broadcast the Event Dispatcher to any receivers. Basically, you are only going to be using Call from the sending object. Generally speaking, the receivers won't have to worry about Call. You might come up with an exception. Bind will create a Bind node. If I go back a few slides, this node is a Bind node. A Bind node is how you are going to attach some event to your Event Dispatcher. All Bind does is create the Bind node, and nothing else. Unbind is going to create an Unbind node. An Unbind node is just like snipping the red Event wire at runtime. It is just like saying, "I don't want you to listen out for this Event Dispatcher anymore". You can also create an Unbind All node. This node will unbind all events from that Event Dispatcher across all objects in the game. For example, you have an Event Dispatcher that was tied to a Character. Let's go back to our boss fight where your great big toad character is fighting the hero. Every time he casts a certain spell it causes all the torches in the room to flare up, the music becomes dramatic for a moment, the camera zooms in, and all these things happen in response. After the boss dies, none of these objects in the level need to be listening out for that anymore. Once the Character is dead and we don't care about him anymore, you might call an Unbind All node to sever all the wires so you are not listening out anymore. Next, we have Event. This is kind of a shortcut. Event will create a Custom Event that has a matching signature. If you don't want to do it by hand, you can choose Event and that will do it for you. Finally, you have an option to Assign. The is another shortcut. Assign will create a Bind node and a Custom Event already wired together. Assign is just a way for you to get the job done a little more quickly. If you know you still need to create the Bind node and the Event node, and you need to wire them up, it is significantly faster to call Assign instead to do the work for you. Let's give a demonstration. Let's talk about Event Dispatchers. I am going to jump back over to the level. Let's make a UI. I chose a UI for a very particular reason, but I will get to that. Right-click in the Content Browser, go under User Interface, and select Widget Blueprint. Call this Widget Blueprint, "HealthUI". I even spelled it right. That is awesome. Double-click to open HealthUI. We are going to build a really, really basic UI. Don't look for anything very fancy here. In the Palette, expand Panel and select Horizontal Box. Drag Horizontal Box into the upper left hand corner. Make it nice and big. That is pretty good. I will bring it box down just a little bit. From the Palette, Drag Text into the Horizontal Box. In the Details panel under Content, set Text to "Health: ", and press Enter. From the Palette, Drag-and-drop a Progress Bar into the Horizontal Box. In the Details panel with the Progress Bar selected, click the Fill button. That will fill in the Progress Bar the rest of the way. In the Details panel, there is a Percent property that controls the Progress Bar, which is great. Fantastic. I want to verify something that will help us later. In the Hierarchy, select the Progress Bar. In the Details panel, check the Is Variable checkbox. The checkbox should be checked by default, but be sure to always double check that. Rename this variable "Health Bar". That sounds like a place to get a smoothie. Now, we have our Health Bar. That is awesome. Click Compile and click Save. Now, let's take a quick break. Go to the ThirdPersonCharacter Blueprint. Let's get the Health Bar so it shows up during our gameplay. I will zoom in. Right-click in the graph, type and select "Event BeginPlay". What are we going to do? Right-click in the graph, type and select "Create Widget". Click the Select Class drop down menu and select Health UI. You do not have to assign Owning Player. I think it is good practice to always assign Owning Player when you are building this kind of UI, so I am going to do it. Owning Player is expecting a PlayerController. We know we are inside a ThirdPersonCharacter Class. We also know the ThirdPersonCharacter Class is also a Character Class, which is a Pawn. Right-click in the graph, type "controller" and select Get Controller. Get Controller is literally making a call to whatever controller is driving our current Pawn. We are controlling the Pawn because Target is set to Self. What controller is driving us right now? It is probably a PlayerController. We need to confirm it is, in fact, a PlayerController. Drag off Return Value, type "PlayerController", and select Cast To PlayerController. If you know this is going to be a PlayerController at all times, you can Right-click the Cast To PlayerController node and select Convert to purecast. Now, the node doesn't even require its own execution wire. That just runs right through. Converting to a purecast is only useful if you can guarantee this will be a PlayerController at all times. This is great for a playable Character, so that will work out fine. We have now created our UI. As a general guideline once I have created a UI, I tend to put the UI inside a variable. Right-click the Return Value and select Promote to Variable. Call this variable "CharacterHUD". Drag off the Set Character HUD output, and type "add to". You will see Add to Player Screen and Add to Viewport. This lecture is not about UMG, but Add to Player Screen is for split-screen. Select Add to Viewport. We are going to keep this simple. Click Compile and click Save. I am not going to worry about the warning; we know it is tied to the Level script. Since it is going to drive me crazy and I have a little bit of OCD, I will select that script and press Delete. You saw that script works, and you saw you can get a streaming Level by name. It only works on Sub-Levels, and you can use it until your heart's content. Merry Christmas. Now, click Play. There is our Health Bar. It is marvelous. It is actually way too long and kind of hideous looking, but it will get the job done. Now, here is the thing. In UIs, particularly in UMG, it is very easy to bind data to a given property. For example in the Details panel next to Percent, I could click Bind. I could select Create Binding. I am not actually going to do it. Create Bind will create a function. In that function I can say to get the owner, make sure it is a playable Character, get its Health, and then drive that using the Bind function. That is great. It will work perfectly. When you bind data that updates on every tick, you can affect performance. You should reserve that and only use it for times when you know for a fact your UI has to update on every frame. More often than not, your UI doesn't have to update every frame. For a Health Bar, it only needs to update when you affect the Character's Health. Updating the Health is completely event based. I have heard exceptions from people such as, "What if I am doing a flight simulator and I have an altimeter where I need a constant read out of what is my current ground altitude, etc.?" You could bind that if you want to, but you will probably discover that you don't have to do that on every single frame. You can get away with maybe doing it 10 times per second. Or, maybe it will be a little or a little less, in which case you use a timer and then it all becomes event based again. My point is not that you should never use binds, it is you should be very careful about when to use binds. We don't need binds in order to drive something as simple as a Health Bar. We are going to go back to ThirdPersonCharacter. Earlier, we were doing some things with our Character's Health. We were updating their health on Event AnyDamage. Then, we also had a Healing Volume we called earlier. I am going to make a change to that Healing Volume. I didn't plan this, but it is something you should know about anyway. Go to ThirdPersonExampleMap and Double-click to open HealingVolume. Do you remember what it was doing? The Healing Volume was grabbing the Health value and setting it. I don't like this as a general practice. I don't like anybody else being responsible for setting a value of an object. You can do it. There is technically nothing wrong with it. Philosophically speaking, I don't care for it. Here is why. If I ever set something the wrong way, I don't want to have to dig through and find how it was set. I would rather go into the ThirdPersonCharacter and create a function. In the My Blueprint panel, click +Function. Call this function "HealAll". From the My Blueprint panel, Drag Health into the graph. Plug Heal All into Set Health. All this is going to do is set the Health property to 100. Set Health to 100. This is set on the Character and not on the Healing Volume. This means the Healing Volume isn't going to do any of this script. Select Set Health and Print String nodes, and press Delete. Drag off As Third Person Character, type and select "Heal All". Now, the ThirdPersonCharacter calls the Heal All function. It is very useful because if I ever care about how much Health the Character has and maybe Heal All should change that value, I only have to go to the ThirdPersonCharacter to set it. It also means other objects that may need to heal the Character can make a reference to that same function. Now, go back to ThirdPersonCharacter and go to the Event Graph. On Event AnyDamange we are going to update our Health, and then we were printing out to the screen. Select the Print String nodes and select Delete. We are going to use an Event Dispatcher instead. Here is how I make it. In the My Blueprint panel, click +Event Dispatcher. Call this Event Dispatcher, "UpdateUI". I need to send this some data that our UI can actually parse. With the UpdateUI Event Dispatcher selected, click the New button in the Details panel. Call this input "Health". Click the input type drop down menu and select Float. Fantastic. You will notice there is also Copy signature from drop down menu. This is where you can copy any signatures. If you had another Event Dispatcher that had the same collection of outputs and you don't want to have to add them one at a time, you can copy the signature from an existing Event Dispatcher. You can set it up once and it will save you time later on. For us, it doesn't really matter. We have built our Event Dispatcher. Drag the UpdateUI Event Dispatcher into the graph and there is a menu. You can read it yourself. We are in the sender, and the sender only has to call. Select Call. It is just like making a Tweet. Plug Set Health into Call UpdateUI. Plug the Set Health return value into Health to transmit our current Health value. Remember our function we created earlier for HealAll? When Heal All is called, it is going to set Health back to 100. Let's make that also call the Event Dispatcher. Plug Set Health into Call UpdateUI. Plug the Set Health return value into Health. Click Compile. We are almost done, but not quite. Go to the Event Graph. Earlier, we added our UI to our Character so we can see it when we play the game, but our UI has a default value for its Percent property. I was playing with something, so the value is ~0.32. As soon as we add this to the viewport, let's also call our Event Dispatcher. You can do this the other way too. Drag a wire off the Add to Viewport output, type and select "Call Update UI". There it is. We need to send Call Update UI our current Health value. Drag Health from the My Blueprint panel onto the Health property of Call UpdateUI. By using the variable for Health, if we ever change the Health default value, it will send whatever value comes in, which is great. Click Compile. Go to ThirdPersonExampleMap and click Play. Nothing happened yet, but that is because we haven't implemented our Event Dispatcher on our UI. Of course, that is the other side of this. If you never make the bind, then nothing is listening; so nothing actually happens, and that is not useful to anybody. Let's go back to UMG. Go to the HealthUI Event Graph. Let's do some fancy things. First, we have Event Construct. This node is just like Event BeginPlay for UI. Right-click in the graph, type "get owning" and select Get Owning Player Pawn. We are not worried about multiplayer, so I don't care about whether it is local player. Select Get Owning Player Pawn. Once we have the owning Player Pawn, we need to make sure that it is, in fact, the Third Person Character. Why? The Third Person Character is where we built our Event Dispatcher. We do a cast to verify we are talking to the right object. Drag off Return Value, type "cast to" and select Cast to ThirdPersonCharacter. Plug Event Construct into Cast To Third Person Character. Now that we have access to the Third Person Character, we can make a bind to that Event Dispatcher. Drag off As Third Person Character, type "bind to" and select Bind Event to UpdateUI. I can bind that and it creates a Bind node, but this is not complete. Drag a wire off Event and you can just click Add Custom Event. Notice, it automatically creates a Custom Event node with a pin for your signature. I was so happy when they added that. We will call this Custom Event something meaningful. Call this "UpdateHealthBar". We have an event that will fire whenever that Event Dispatcher is called on the Character. I will select the Bind node and Custom Event, and press Delete. I mentioned that once you have access to the class and you know where your Event Dispatcher lives, you can assign UpdateUI. Drag off As Third Person Character, type "assign update" and select Bind Event to UpdateUI. Selecting Assign will create your Bind node, it creates your Custom Event node, it connects them, and it is just waiting for you to give it a name. Call this Custom Event "UpdateHealthBar". Selecting Assign is a little bit faster. I recommend using it as part of your workflow because it saves a few clicks. Cool, that is now connected. Now, where do we go from here? In the My Blueprint panel, select the HealthBar. Select the Designer tab. We made sure Is Variable was checked on the Designer tab for the Health Bar. Now, we see HealthBar listed in our variables. Drag a reference to HealthBar from the My Blueprint panel into the graph. Drag off Health Bar, type and select "Get Percent". Actually, we need to drag off Health Bar, type and select "Set Percent". Thank you. Now, here is the thing. As you might recall, Percent is a 0 to 1 value, and not 0 to 100. We need to convert something that goes from 0 to 100, down to 0 to 1. That is very easy; we just need to divide it by 100. Drag a wire off Health, type "/" and select float / float. Set B to 100, and press Enter. Plug the result into In Percent. Generally speaking, we should be good to go. Now, let's do something else just because it is fun and because we can. Drag a wire out from Health Bar, type "color" and select Set Fill Color and Opacity. Let's set this. Drag off the incoming Health value, type "<" and select float < float. Set the value to 0.2, which is 20%. Hold B + Left-click to create a Branch node. Plug the result of the float < float into the Condition. Please tell me you are about to Tweet that, Chance. Chance Ivey: Not that one. Zak: [Laughing maniacally] I am getting photobombed right now. That is not how it works, but it is something. What are we doing? We are taking the incoming Health, dividing the Health down to our percent, and if it is less than 0.2 or 20%, then set the Fill Color and Opacity. Click the Color property and select red, so that we know we are about to die and we can be truly afraid. Apparently, I am way too picky about the color. Click Compile and click Save. Go to ThirdPersonExampleMap. Hopefully it all works and I didn't break anything, but you never know until you try. Click Play. Our Health Bar is all the way at maximum, which is great. Remember, the Health Bar had a default value of somewhere between 0 and 1. Let's go stand in our PainVolume. Our Health Bar is getting low. Let's leave that and go get healed on the Healing Volume. The Health Bar fills up. Let's test the color. It is going down and we are hurting more. This is taking forever. [Zak singing, then grunting] It turned red; we are almost dead. Then when we heal back up, nothing is turning the Health Bar back to blue. Go back to HealthUI. Select the Set Fill Color and Opacity node, press Ctrl + C to Copy it, and press Ctrl + V to Paste it. Plug False into the copy of Set Fill Color and Opacity. The truth is that I have no idea what the default color was, so I am going to cheat. Go to the Designer tab. In the Details panel, Double-click the Fill Color and Opacity property to open the Color Picker. Press Ctrl + C to copy the Hex value. I should probably know the Hex value off the top of my head at this point, but I don't. Click In Color property and press Ctrl + V to Paste the Hex value. Press Enter. Ignore the candy wrapper. [All Laughing] Click Compile. What is it saying? It is saying that we don't have a Target. Well, of course we should have a Target. Also, wires that are this long drive me crazy. Select the Health Bar variable, press Ctrl + C to Copy it, and press Ctrl + V to Paste it over here. Let's have a closer version of Health Bar, and plug it into Target. Click Compile. Everybody should be happy. Go to ThirdPersonExampleMap and click Play. [Laughing] You know what? That won't work very well, will it? I wanted to make it so taking damage wouldn't take as long. I guess I have to change more things than I want to. So we will just wait. It is red. I didn't die though. Then, we are healed. Now, we are pretty much done. That is all the Blueprint communication I wanted to show. I am going to do one more thing just for giggles. We are doing all this script to check if Health is below 0. We only care about this from the perspective of damage. I am not going to go overboard. Drag off Health, type "<" and select float < float. If Health ever equals or goes below 0, then let's do something kind of funny. Let's do something. From the Components panel, Drag Mesh into the graph. Let's do something else too. Grab the Mesh. From the Components panel, Drag the CharacterMovement Component into the graph. Let's disable this. Drag off Character Movement, type "disable" and select Disable Movement. This is so our Character can't move when he dies. Drag off Mesh, type "collision" and select Set Collision Enabled. We are going to enable collision on our Mesh. Plug Disable Movement into Set Collision Enabled. Click the New Type drop down menu and select Collision Enabled (Query and Physics). Next drag off Mesh, type "simulate", and select Set All Bodies Simulate Physics. Check the New Physics checkbox to set it to true. Plug Set Collision Enabled into Set All Bodies Simulate Physics. Drag another wire off Mesh, type "blend weight" and select Set All Bodies Physics Blend Weight. That is what I wanted. Plug Set All Bodies Simulate Physics into Set All Bodies Physics Blend Weight. Set Physics Blend Weight to 1 so we are blending all the way over to full physics simulation. As a review, we have a Branch node. If Health is equal to or less than 0, we are going to disable the Character Movement Component, we are going to enable collision on our Mesh, we are going to tell all our physics bodies to start simulating. Then, we are going to tell them to blend all the way over to pure physics simulation so we are not paying attention any more animation from the Animation Blueprint. Now we can go to the PainVolume and take damage. I will turn and face the camera because it is funnier. The Health Bar gets lower and lower. Oh my, we are in danger! It is red. [Mimics death noise] That is me every Monday morning, right there. I am going to do something for no reason other than it is funny. In the Details panel, set Damage Per Sec to 100. From the Modes panel, Drag in a Cylinder. This is just bonus for impressing your friends to show them all the cool things you have done in UE4 lately. I will put a Cylinder in the middle of this volume at about head level. Click Play. Run right into the PainVolume and wham! I don't know why that is so satisfying, but it kind of is. If you need to see it from the side, which I do, then there you go. That is just something fun to play with. That is it, right? We have talked about all different forms of Blueprint communication. Are there any questions specifically about Event Dispatchers? Let me take a look over at our list of questions. For an interact system, would you recommend a Blueprint Interface system like you showed? I am currently using an Event Dispatcher bound to an interactable parent object, which validates if interactable. That is completely valid. It is really up to you. There is even a third way to do it, which you may not have even considered. You can have a Parent Class which defines whether something is interactable. You could have a Parent Class called Interactable Object, and that can have the behavior for when it receives an Interact Custom Event. Then, everything that is inertactable can inherit from the parent and become Child Classes. That is just as valid. These are philosophical questions. I am not going to tell you the way you are doing it is right or wrong. Keep doing what you are doing, and you will find a way that works best for you. I feel like you should probably try all of the different forms of Blueprint communication, and see which you are comfortable with and see which makes the most sense. If you have multiple developers, make sure they are all on the same page. We will talk about that in just a second. I wouldn't necessarily recommend it, but I also wouldn't discourage it. That is the nature of a scripting language, which is all Blueprint is. There are a million ways to do everything. You have chose another one of the million than what I showed you. Next, any tricks to manage all of those event Blueprint wires and keep it pretty? I think somebody asked this earlier in the forums, and I told them what to do. I guess I should demonstrate it as well. Go to HealthUI. We have this Bind Event to UpdateUI. You have to have this Event wire. This is just how it goes. If you end up in a situation where you had to have this script sitting over here and you didn't like having a long wire as sometimes these wires get really long, in that case I would hold Alt + Click to snip this wire. Drag a wire out from Event and select Add Custom Event. Call this Custom Event something like "UpdateUICalled". Drag off the output, type "update" and select Update Health Bar. Plug Health into Health. You are doing the exact same thing, you are just keeping the wire nice and tight. Now, there is a wireless connection from this node to that node. That will keep the script a little tidier, but you can't get rid of this Event wire. You can create a Reroute node if you want to reshape the wire, but that is all you can do. Does Destroy Actor handle the Unbind call? No, it does not. You have something you don't have a reference to, and the listening is still there. Make sure you unbind on death. There is already an Event Dispatcher that exists for all Actors called On Destroyed. Drag off As Third Person Character, type "on destroyed" and select Assign On Destroyed, so you can stop listening and unbind everything. Is it possible to make the image blurry when Health is low? The answer to your question is yes, but there is no easy way to do it because there is no post-processing on UI at this point in UE4's lifecycle. What you would have to do is swap out for a series of textures that were blurry themselves. This is very involved and is way off-track from Blueprint communication and starts talking about UMG. That is enough to get you thinking. Before I start getting into all the generic questions, let me jump back to the slide deck for another second. I want to run through a quick conclusion. There are some things I want you to think about and some last minute notes to write down. As you have seen, there are three (3) ways to get Blueprints to communicate. There are a lot of different ways you can implement those three (3) different types of Blueprint communication. In many cases, more than one approach to Blueprint communication will apply, which I was just talking about just a moment ago. Just because there are other ways to do it, doesn't necessarily mean that you are wrong. It doesn't necessarily mean that you are right. You need to consider all the angles we discussed here, and it should become clearer which method to use. Also, make sure you get together with your team to make sure you are using the communication method that works best for everyone you are working with. Like with interaction, maybe you have a situation where an Event Dispatcher will work just as well as a Blueprint Interface. Make sure everybody is on the same page about communication so you don't have some developers doing it in a Blueprint Interface, and some using an Event Dispatcher. On that note, unify and standardize. This has nothing to do with Blueprint communication. It has everything to do with using Blueprints in general. Particularly if you are on a team, please think about this. Agree on what types of approaches you are going to be using under certain circumstances. If everyone is handling communication differently, it is really hard to work together. That is true for things beyond communication. Make sure you have a set of standards that everybody is using for the Blueprints you built. Ideally, your team will make a set of Blueprint coding standards or a series of rules. Here is what you should be naming variables, or here is our naming convention. Here is the way you should be ordering your nodes. Here is how you should be naming your Custom Events and how many Custom Events you have. Here are the maximum number of components you should have. Here is the maximum number of nodes you should have. There is actually more than one studio I have talked to in my travels where they have written their own plug-in for the editor so if you add more than 100 nodes to your Blueprint, a modal window pops up and says, "Go contact a programmer right now because you might be doing it wrong". Keep these kind of standards in mind. If you have a single Blueprint with 500 nodes, you are probably adding too much functionality into that Blueprint. It is the same in code. When you are building a code class, you want to keep the amount of functionality in that class as minimal and as compact as you can. Think about these kinds of things. Build these coding standards, use them immediately, and enforce them all the time. Every team is different. As a result, Epic doesn't have a single coding standard that we think everybody should use when it comes to Blueprint. You are going to have to work with your team to come up with a style that works best for you, and then implement it from there. At some point in the future, it is possible that we may have a sample coding standard that you could pull from. At the time of this video, we don't have that kind of thing. Keep that in mind, and I will get off my pulpit. We will move on. Now, are there any remaining questions over anything? Let me scan back over and see if there are any questions I missed. How do you send variables from Level Blueprint to Anim Blueprint? It is easy if the Level Blueprint can get a reference to the Character or whatever it is that is being animated. Once you have the Character, you can get that Character's Skeletal Mesh Component. The Skeletal Mesh will give you access to the Animation Blueprint. Then, you can send data in the Animation Blueprint. Personally, I would never do that. I wouldn't have the Level Blueprint necessarily ever need access to that kind of thing. I would have some overarching class handle it. It could be the Game Mode, it could be a Game State, it could be the Game Instance, it could be a custom class that I am adding on my own, etc. Because communication with the Level Blueprint... Notice I am not saying Sub-Level. Specifically with the Persistent Level because it is a little bit dicey, I try not to work that way. You have seen how you could do some things with the Sub-Level that might be helpful. Let's see what is next. We talked a little bit about the inherit classes question. Can I transfer the knowledge I will gain to C++? Can I just take Blueprint nodes for casting and look them up in the framework, and use the same functions for C++? Generally speaking, the answer is yes. It is a little bit different for Interfaces. Interfaces are implemented differently in code than they are in script. That is just the nature of the beast. I am not going to be the guy who can tell you how to implement them in C++. I will be perfectly honest, I am not a big fan of the way they work. They are good. If you are a programmer, use them; but I don't like them. Next. Why is there a Pain Causing Volume? We talked about that. How do you reference a component of another Blueprint? Does the target need to be the component? Or does the target always need to be the same type of Actor? Well, you have some options here. There are some special nodes that will give you access to a particular component like Out Hit. A hit result can tell you what component you hit. That can be useful. Some types of overlaps, like component overlaps, can give you access to that component and you can go from there. Beyond that, once you have a reference to the Actor, you can then go into any component that object has. You can drag a wire out from that Actor, and you can now access any of the functionality that exists on his components as well. Maybe he has a Character Movement Component. You can get a reference to the Character, and say Get Character Movement Component. Then you have access to that component. If you are looking to get the component as an initial reference, there are only a few things that can do it like some hits, some overlaps, and maybe a few other things past that. How would a damage increment work with protection like armor? I know everybody loves to hear this answer, but it is up to you. It is how you would like to implement that. What I would do is I would actually have two (2) sort of health bars. You would have your Health, and you would have your Armor. The amount of damage your Health takes is scaled by what is here in the Armor. That is one way to do it. In that way if someone hits your heavily armored character with an axe, the character takes a little bit of damage but the armor takes a lot of damage. Or, there is the other way where you can think of armor like a shield. No damage penetrates to the Character as long as the shield is up. You are hitting him with the axe and the Armor goes down. When Armor hits 0, then you are affecting the Health. It is really up to you. At that point, it is just a matter of multiplying some numbers together. That is really how you decide for your game to work. That is a little too specific for us to delve into in this discussion. Hopefully, that is enough of an answer to start. Is it best practice to create health as a Blueprint Component and use Blueprint Interfaces rather than Direct Blueprint Communication for every Actor that has Health? I think we kind of discussed that earlier. I would probably have a base class that owned Health. I could use either Direct Blueprint Communication or I could use Blueprint Interfaces. To me, it hardly matters. Use whatever feels right to you and the rest of your team. If I want a function to affect multiple enemies in a game, I would generally just do an AOE. I would get the array of all the things, and run a For Each Loop on them. Alternatively, you could have that AOE basically send out an event and a reference to itself so these things could tie into an Event Dispatcher. However, that seems a little heavy handed to me. I don't think I would do that. I would probably just stick to creating an array for everybody you hit, loop through that, and then maybe use a Blueprint Interface to affect their Health. All right, next question. Is there a way to actually check if an Actor is visible inside the viewport? That is outside the scope of what we are talking about. I like to keep these questions narrowed down. That is a great question to put on the forums though. What is the next question? Does having many Event Dispatchers slow down the game? We talked about that. It shouldn't be weighing down heavily, but again, testing is the best way to go. Generally as a rule, I would advise you never to overuse anything in Blueprint. Don't put too many nodes in Blueprint. By that, I could means hundreds of nodes. Just be cognizant of that. Don't overdo it. Don't put too much functionality into a single Blueprint. Don't add too many components to a Blueprint. Don't have a huge complicated hierarchy of Parent and Child Classes. You might be overdoing it there as well. Try to keep your Blueprints simple. As soon as you start having to get into the much more hardcore relationships, it is possible you should be learning a little bit of C++ or grabbing a programming friend. Somebody said they are using Event Dispatchers to do interactable actions. That is fine. It is whatever works best for you. I could just as easily set that Door up to open and close based on an Event Dispatcher. When we get close to the Door, we engage the Event Dispatcher and start listening. When I walk away from the Door, we stop listening. Then when I hit the button, all that would happen is we would make a call to Interact, and that would work. That is perfectly valid. Does Destroy Actor handle the Unbind All? I think I answered this question. My answer is no. I am 99% sure of that. There is a 1% margin of error in there. That might be a good question to put on the forums. Is it possible to make an image blurry? We talked about that. Can you tell a bit more on performance on binding materials in UMG? I am only binding to variables, not functions, but it is a lot of variables. You should be fine. Binding is not that expensive. Sure, there is a cost to it, but there is a cost for everything your Character is doing. You could have many, many binds. Notice, I am not actually including a number in that statement. You should be just fine. Just keep in mind, only have them open when you need them and disconnect them when you don't. Either way, it is still one of the cheapest ways to send data up to something like a UI. I wouldn't be that scared. Let me put it to you another way. If you have so many binds that you are scared about it, your UI probably has too many things on it. By that, I mean it is just a solid window of nothing but UI bits, and you can't make anything out of it. Anything short of that, you are probably just fine. Outside of that though, you should run profiles. You should run your CPU profiler on your UI, and see where it starts to get heavy. Those are all of our questions. I wanted to thank everybody for watching. We went a whole lot longer than I thought we would, but that is perfectly fine. Please make sure if you have any questions to post them in the forums. I will be keeping an eye on our announcement thread for at least the next couple of days. I will try to answer any further questions in the forums as I have time. Thank you all for joining. Thank you all for watching. Thank you so much for using UE4. Please let us know when you are making cool things. Put your project in the forums, Tweet about it, and let us know so that we can shout out when you make cool things. With that, until next time. This has been another Unreal Engine training stream. We will catch you on the next one. ♪♪♪
Info
Channel: Unreal Engine
Views: 199,244
Rating: undefined out of 5
Keywords: Unreal Engine, Epic Games, UE4, UDK, Unreal, Game Development
Id: EM_HYqQdToE
Channel Id: undefined
Length: 142min 5sec (8525 seconds)
Published: Wed Feb 24 2016
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.