How to Create a Pickup System

I am trying to create a system where when the player looks at a particular item, a widget will come up that says “E to Collect Wood” for example. Or “E to Search Crate”. If the player presses E while hovering over this particular item I will then give a piece of wood to them or whatever needs to be done. And if the player only looks at it but does not pick this particular item up and decides to walk away without pressing E, nothing would happen. Similar to Alien Isolation:

Or fallout New Vegas:

What I did was creating a rectangular box attached to the camera and when it overlaps, a widget will display, ect. However, when I do this and the player doesn’t decide to pick up that particular actor and just look at it, but then switches to another, the original actor they just looked at will be destroyed instead. It’s also not very accurate when trying to collect. Sometimes even looking straight at the desired actor will not be enough for the box to overlap. I am wondering if there is a more simple way to go about doing this system using widgets? If anyone could teach me or help me learn how to do this it would be very appreciated, thanks!

you’ll want to look into ‘line tracing’ aka ‘raycast’.

Hi, so what I would do and probably the easiest way is:

  1. In your Player blueprint, create a bool var called “Epressed?”

  2. No when you press E set that bool to true and when the button is released set it to false.

  3. In the desired actor blueprint (Door,Box,Wood etc…) add a Box Collision component. Select that box and in the
    Event graph create OnComponentBeginOverlap (OCBO in short) , and OnComponentEndOverlap (OCEO).

  4. From OCBO cast to your Player and create the desired widget. (Dont forget to add it to the viewport) Now connect Object to Other Actor and from the as Player get your “Epressed?” bool and check if true (With branch). If true do the desired action. If false create a loop.

  5. My way of creating a loop is to create a Sequence and a Gate. From sequence connect Then 0 to Open ( so it first opens the loop) and connect Then 1 to Enter. In the Exit Once again check if “Epressed?” is true, if it is true then do the desired action and Close the Gate so it stops looping. If not then make a delay and connect it back to Enter from the Gate. So it loops and checks again.

  6. Now from OCEO (OnComponentEndOverlap) just Close the gate. So if the player just walks out of the range without pressing E it will stop the loop.

Let me know if that works for you, and feel free to ask my any questions :slight_smile:

I had created a tutorial a long time ago which someone wanted to know how to pick up, and switch through weapons here is the link

it doesn't use a menu, but you could easily implement a UI with it

It depends on if you want to pick items up that you are in proximity of or you want to also be looking at the items before it displays the pick up widget. If you want to have players have to find items, it might be better to use a line trace.

If you just want to be in proximity just use a branch off of a key press event in your character bp controlled by a bool that gets switched on and off by an overlapping collision volume on your item bp. Similar Sntfon100’s answer.

If you want a line trace system, start by adding a couple bools to you character blueprint for “is near” and “is looking at”.

Set up your item bp with a collision sphere.(the distance you want to be able to pick up items within) On the static mesh it’s important you set the Object Type under Collision Presets to what ever you are going to use in your line trace. You can make new object types and trace types in project settings.

Set up overlap events for the collision sphere to control the is near bool in character bp like so.

In character bp set up branch on tick to control when line trace happens based on “is near” bool. Also be sure to use the correct Object Type (same as static mesh in your item bp) in the make array node hooked up to your line trace.

,

Now with the hit result from the line trace we are going to check if we are hitting our item by casting and check that we are in fact hitting the static mesh with the following branch. Then set “is looking at” based on success of casting and comparing component hit to static mesh component. Also set a sub class reference so you know anything you do past this point will be done to this specific object.

Now just use the key press event to complete the logic, do what ever you do for your inventory. destroy the actor you just picked up and the reset the bools to false.

For the UI I just created and added it at beginning of play in character bp. Then bound the text visibility in the widget to the “is looking at” bool.

End result is this.

Is there a way to do this so the widget and everything else only displays if the player is actually looking at the actor? With the setup you have showed me the player could be facing the opposite direction of the actor, but still be in the box collision around the actor and have the widget display and be able to pick it up.

I just noticed that, thanks!

There is an answer for specifically that down below.

I have another issue that still persists when doing this. I have one type of actor (a crate) and I have multiple crates copied into the scene. The issue is, when I look at one crate but don’t pick it up, and then decide to look at a different instance of the crate (but still the same actor) and press E, the affect I wanted on the actor I am looking at will be given to the actor I had looked at previously. I am trying to destroy the actor that they press E on but for some reason it is targeting the wrong instance of that actor. Do you know if there is a solution to this?

My bad, I was a bit short sighted, I didn’t think about multiple items being in close proximity.

First of all you will need to move the Setter of pick up sub class to the end of the exec so it confirms you are pressing e on the item you are looking at.

You will also have to create an array in your character bp for “objects near by” of the actor type your pick ups are. Then we add and remove from the that array with the overlap events and use a branch to determine if we are still standing near the item.

I also removed the a setter for “is near” in the character bp on the e pressed exec line, as it will just cause us problems now.

Sorry for the mistake this should work better, let me know if you have anymore problems.

In the line trace first check if it’s a blocking hit, if false clear the PickupSubClass reference, if true cast to your pickup class if the cast fails again clear the reference (by setting it to nothing) if it succeeds set the the PickupSubClass to the result of the cast that’s all you need.

When you press E simply check if PickupSubClass is valid, if true (meaning you’re looking at a pickup) destroy etc.

Extra: to avoid casting every tick after you’ve checked that it’s a blocking hit check if the PickupSubClass is not equal to the HitActor (If false it means you’re still looking at the same pickup) this will save you some performance.

I’m not sure how to create that set sub class node. Could you explain to me how were able to get that node?

It worked. Thank you so much, I’ve been stuck on this forever!

My apologies, I guess I didn’t quite understand the question.
But i’m glad to hear you found an answer!
Best of lucks :slight_smile:

It’s a variable in the character bp you can create it manually or drag off the cast node and click promote to variable.

That’s a good idea.