Hey all. I recently figured out a neat way to create a simple yet effective interaction system for use in my current UE4 indie horror game, Hypnopompic, but I thought I’d share how I made it. This was done in UE4.12, but it should work just the same in 4.10 and 4.11, and maybe even earlier versions. So without further ado, here we go!
First, just to stay organized, create a folder called “Interaction.” This is where we’ll keep the blueprints.
Create a blueprint interface (right-click in the content browser, under Create Advanced Asset, hover over Blueprints) and call it “Int_Interaction”
Open up your interface, and rename NewFunction_0 to “OnInteracted” (right-click it under Functions on the My Blueprint panel on the right of the screen). Compile and save.
Open your character blueprint, and add an event for the key you would like to use (or create a custom action mapping, as I did, named Interact). Add a LineTraceByChannel.
Get your camera (First Person Camera in my case, as I’m using the first person template) and get its WorldLocation. Plug that into Start on the LineTraceByChannel.
Get your camera’s WorldRotation. Drag out the Return Value on that, and get the Forward Vector. Multiply the return value by a float. The number you multiply it by is how far away an object can be for you to interact for it. For instance, if you use 500 like I did, you can interact with anything up to 500 units away. Add that to your camera’s WorldLocation and plug that into End on the LineTraceByChannel.
Drag out the Out Hit on your LineTraceByChannel and add a Break Hit Result node.
Drag out the Hit Actor from the Break Hit Result, and add a Does Implement Interface node. For the interface, select the Int_Interaction that we made a moment ago. Drag out the Return Value and add a branch. Connect the branch to your LineTraceByChannel, and drag out True, and add an On Interacted (Message) node. Connect Target to Hit Actor from your Break Hit Result. Essentially what this is doing is, when you use your interact key, it’ll check if you’re looking at anything that’s within the specified distance. If so, check if it’s using the interface we created. If it is, activate an On Interacted event inside of it. We’ll get to that next. Compile and save.
Open your interaction folder and create an actor blueprint (right-click in the content browser, click Blueprint Class, and choose Actor). Name it BP_Light_Switch. Open it up. Click on Class Settings on the Toolbar panel, then on the Details panel, under Interfaces, click Add, and choose our Int_Interaction interface. This will add our interface to this blueprint, so that we can use any functions from it.
In the Components panel, click Add Component and add a static mesh and a box collision. Name the static mesh “Switch.”
Go into your Viewport. Scale out the box to go outside of the mesh like I have. This is so that if the player isn’t directly looking at the light switch when they interact, they can still be looking at the box and interact with it - because the light switch is small, and easy to miss. Select the Box Collision, and in the Details panel, look under the Collision section. Set the Collision Preset to Custom, and expand that. Set it to Block everything, but only Overlap the Camera and Pawn. This is so that you can still interact with it, but you won’t collide with it.
Add a variable and name it Target. Set the Variable Type in the Details panel to Light, and make it an array by clicking on the 3x3 blue grid beside it. Tick “Editable”. Making it an array allows you to add more than one actor at a time (this way you can toggle more than one light at once. You may not need this in every case) and making it editable allows you to change this value outside of the blueprint editor - so that you can easily reference actors in the current level.
Go back into your Event Graph. Add an Event On Interacted and a ForEachLoop. Connect the two, and plug your Target variable into the Array. Drag out the Array Element on your ForEachLoop and add a Get Light Component. Drag that out and add a Toggle Visibilty node. Connect that with the Loop Body from your ForEachLoop. This is basically saying, when someone intreacts with this, it’s going to get each Target you have set, get the Light component, and toggle it - so if the light is on, it will turn it off, and if it’s off, it will turn it on. Compile and save.
Go to your main editor viewport, where you can see your game’s level. Drag a light (point or spot) and your BP_Light_Switch into the map. Select your BP_Light_Switch and in the Details panel, go under the Default section. Beside “0 elements” press the + button. Beside 0, click the dropdown box on None and select your light. You can do this as many times as you want for however many lights you want. They’ll all be toggled at the same time with the press of this switch. Save and compile. Start up the game, stand near your light switch, look at it, and press your interact button. The light should turn on or off, depending on what state it was already in.
Enjoy! Hope I explained this well, this was my first tutorial. If you have any questions or anything, feel free to ask in the comments!
EDIT: Forgot to mention something: you can easily add more interactable actors, aside from the example light switch provided, via the same method. Just create a new actor blueprint, in the class settings, add the interface, and add an Event On Interacted. Make sure the actor has some sort of collision so that your LineTraceByChannel can hit it. Whenever you interact with it, it’ll immediately activate your Event On Interacted node and whatever is connected to it. For instance, adding an Event On Interacted and plugging that into a Print String node with the string set to “Hello” will cause it to print “Hello” whenever you interact with it within a certain distance. These are pretty simple examples, but there’s quite a lot you can do with this. Enjoy!