x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

How to Set Up Source Engine-Style Inventory Scroll?

I would like to implement an inventory system similar to the ones in Half-Life, TF2, and L4D, i.e. all of my available weapons and items (starting with one item and going up six total depending upon what items the player has picked up) are in a list on the HUD and the player scrolls to cycle through them. I found this suggestion, but the given answer has got me stuck on step three. Can anyone provide some more detail on that suggestion or perhaps an entirely new one?

Product Version: UE 4.21
Tags:
more ▼

asked May 19 '19 at 03:17 AM in Blueprint Scripting

avatar image

Arro-Wing
10 3 2 4

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

1 answer: sort voted first

Here's what #3 of @mightyenigma 's suggestion is saying:

alt text

This will keep the value in range 0-4 as you scroll the mouse wheel up / down.

capture.png (106.7 kB)
more ▼

answered May 19 '19 at 08:17 AM

avatar image

Everynone
15.3k 77 26 64

avatar image Arro-Wing May 19 '19 at 04:08 PM

Thank you, that makes that a lot clearer. My next question is how best to, I guess, skip integers that correspond to weapon slots that are currently empty.

In my case, the player starts with only a sidearm that takes up slot number 2 (and I guess by extension would make it integer 1). Then as other 5 item slots are filled, more and more of the integers would become available. The only way I can think of to do this is a big mess of branches depending upon what value the integer would be placed at upon incrementing/decrementing and whether or not X slot is filled and if it's empty increment/decrement the integer again, but this seems like it's not the optimal way of going about this.

avatar image Everynone May 19 '19 at 04:18 PM

skip integers that correspond to weapon slots that are currently empty.

Makes sense. What exactly are you slots now? How do you know that a slot is empty?

a big mess of branches depending upon what value the integer would be placed at upon incrementing/decrementing and whether or not X slot is filled and if it's empty increment/decrement the integer again, but this seems like it's not the optimal way of going about this.

It sure would work. But we're better than this. Let me think about it. I'll get back to you.

avatar image Arro-Wing May 19 '19 at 04:27 PM

I have six total slots. At the start, only slot 2 is filled (and it can never be emptied). Currently I have a Boolean for whether or not each slot is filled that also sets some colors on the HUD (i.e. "No Primary Weapon", "No Large Item"). There are also Booleans for whether or not each slot is the currently selected one to do more color changes (i.e. "Primary Weapon is Drawn", Large Item is Drawn").

Once again, I really appreciate you taking the time to help me.

avatar image Everynone May 19 '19 at 04:48 PM

I see. There are many ways of handling it. The most common one would look like this:

  • assuming here that you're using just widgets to represent the slots

  • each slot is a separate widget that is placed (or added dynamically) to a panel

  • each slot is responsible for understanding whether it is empty or not, a slot holds onto an isEmpty boolean

When scrolling with the mouse wheel, rather than increasing the index by one, you loop against the children of the panel holding the widgets - start at the currently selected slot and check the next / previous (mouse wheel up / down) slot - does it have isEmptu {T} flag.

You keep iterating until you've found a non-empty one or until you've covered all children - you can use Get Children Count for this.

This probably sounds fairly complicated.

avatar image Arro-Wing May 19 '19 at 05:01 PM

Okay, so I need to take my individual slots out of the main HUD and rebuild them as their own thing to then re-add them to the main HUD as children. Got it.

It sounds a little complicated, but maybe I can figure it out once I've got my HUD situated the way it needs to be.

avatar image Everynone May 19 '19 at 06:52 PM

Have a look at this, perhaps it will inspire you.

This is my slot:

alt text

Calling this event highlights the slot, making it selected. The slot has isEmpty variable so it knows whether it has something or not. And it has an exposed MyIndex variable so it knows its place in the parent panel.

The panel that holds the slots:

alt text

This panel also handles mouse wheel input:

alt text

The function fires a custom event and sends the direction of the scroll. It also informs the Player Controller that it has Handled mouse input so the controller can no longer interpret it - so you do not accidentally zoom in / out the camera when browsing items, for example.

And here's the iteration loop, only one direction because I run out time:

alt text

Image from Gyazo


It needs more work, the mouse scrolls in the wrong direction for example. It's a matter of ticking some bools in the mouse input I think. And you'd need to add the index finding in the opposing direction.

I think it could be a half-decent start. I've made carousel menus before but never one that has to skip elements. That's how I'd approach it and it seems to be working. Promising.

Do tell if any of the elements are odd-looking.

slotwidget.png (107.5 kB)
panel-contructs.png (247.7 kB)
mousewheel.png (122.2 kB)
iteration.png (404.9 kB)
avatar image Arro-Wing May 19 '19 at 10:01 PM

Thank you for going into so much detail, but I'm still super confused. (Sorry!)

So I change my slots to get their color in the event graph as per your example. That seems to work fine. My problems begin when I try to do the next step.

I think one of my problems might be that you seem to be using the same widget as the basis for every slot in your inventory but each of my slots are their own blueprints because they have entirely different setups. When I added my slots to the viewport, I think I got six extra copies of each slot (in addition to the original copies even though I never specifically added them to the viewport in the first place so I don't know what's going on). My best attempt at coming up with my own solution gave me this, which I would think would add everything to my array just fine but apparently it's not.

alt text

(Edit: Just noticed that the second "Primary" node should be a "Melee" Node, but I high doubt it's making any sort of difference.)

For some reason, I can't for the life of me get my array to allow me to reference the "Is Selected" function from my Sidearm (the slot I'm testing ATM). When I try to pull off the Selected Slot node it tells me that "User Widget object reference is not compatible with Sidearm object reference". And this is of course extending down to later on, like right after the For Each Loop With Break where you get the selected slot's "Is Empty" Boolean and plug it into a Branch. I can't make the connection.

I'm really sorry if this is a major noob problem (which it probably is).

inventory-1.png (117.1 kB)
avatar image Everynone May 19 '19 at 11:24 PM

I think one of my problems might be that you seem to be using the same widget as the basis for every slot in your inventory but each of my slots are their own blueprints because they have entirely different setups.

Pretty much, yes. One slot for everything because slots are identical, the items the slots hold are not, though.

Can you roughly clarify what is different about each slot? Perhaps I'm misunderstanding something and your vision is more complex than I think.


Generally speaking, you'd want to make slots the same class - the same widget blueprint and duplicate it (either manually like you do, or automatically like I did).

That is because all slots should share certain common functionality like highlights, sounds, animations, ability to display tooltips about the held item, having the empty / full state and so on; and you definitely do not want to manually repeat the script that does all that for each slot.

A slot can have a variable (enumerators work well here) that dictates what item it can hold, and reference an Item the player carries.

This allows you to tell this generic slot to DropItem, ShowHighlight or play 'Beep' sound when the mouse enters, no matter what item it holds. It's a layer of abstraction.


The same goes for the actual items. They should share a base Item class because player can Use, Drop and Place them in the inventory and Equip them. Primary and Sidearm inherit from Item class and create Firearms subclass (that can fire bullets), Grenades inherit from Items but are so different from Firearm subclass that they deserve their own subclass, and so on.

avatar image Arro-Wing May 19 '19 at 11:45 PM

This is what I'm trying to get. (I'm working on a L4D fangame, so that's why I'm trying to replicate this type of HUD.)

alt text

I can definitely see where the bottom three could be easily based off of the same slot widget but I foresee the top three being a little bit more work. I'm guessing I should just build the base widget with all of the setups needed for every single slot and then have a check for which slot is actually used and disable everything that doesn't pertain to that slot?

inventory-2.png (22.9 kB)
avatar image Everynone May 20 '19 at 01:12 PM

I'm guessing I should just build the base widget with all of the setups needed for every single slot and then have a check for which slot is actually used and disable everything that doesn't pertain to that slot?

This is would work and allows you to treat all of them in a similar fashion.


Another method is via an Interface - it allows for communication between classes that are not related.

You can have 6 completely different widgets implementing the same interface - you ask a widget to do a thing - and each will have a unique version of the action required. But it still requires you to duplicate / write code 6 times.

On the other hand, 6 times is not the worst thing in the world. If you later on decide that you need to refactor something, you'll need to deal with the consequence of doing multiple times, though.

avatar image Arro-Wing May 24 '19 at 03:00 AM

Okay, so I was getting quite frustrated and decided to put this particular problem aside for a couple of days to let it marinate in the back of my mind.

After lots of thinking, experimenting, and looking at multiple inventory system tutorials, I think I have my inventory working visually. All of my individual slots are the same widget, with my specific setups for each panel category being enabled or disabled according to the slot's index value and a category Enum. I have copied your provided setup except for two things. Going off of this tutorial, I manually placed my slots into my Inventory widget where I can manually assign them the desired index values. This bit seems to work perfectly fine so far.

alt text

(I just realized this looks exactly the same as my last attempt, but my widget references are referring to my manually-placed (and named) slots that are all derived from the same widget this time as opposed to all being different widgets like last time.)

The only other thing I've changed is that my "Slot Is Selected" event toggles an "Is Selected" Boolean which is one of the variables that set my slots' colors as needed. Your mouse wheel function is copied over as-is, and I've also managed to solve my array-setting-and-calling problems so that I was able to copy your iteration setup as well.

It's still not working, though. I've tried attaching a print string to my "Is Selected" even toggle to see if something happens, but I'm not getting anything. I've been trying different things to try and fix it myself, but I think one of the things confusing me is that I'm not entirely sure what the purpose of your Int Map array is, and I suppose I'm also not sure if I've even set it up the right way (I just created a new array of integers).

inventory-3.png (99.9 kB)
avatar image Everynone May 24 '19 at 06:05 AM

the purpose of your Int Map

It's just an empty array of ints that tells us the order of the slots to step through, looking at you Make Array node:

  • if you start at slot 3 and want to check all slots (to see whether they're empty) in the down direction, you need to check slots 4,5,0,1,2.

  • if you start at slot 4 and want to search up, you need to check slots 3,2,1,0,5.

As you see, the value has to be wrapped - that's what modulo does. It creates an ordered list for the loop that follows to step through, so it does not miss an element. It would not be necessary if you just wanted to scroll up / down without wrapping from the beginning / end.

We have 6 slots and each slot knows where in the array it sits (myIndex) - I did this automatically by spawning slots and assigning this variable

For this to work the MyIndex variable has to be Set for each slot. 0 for slot 0 and 5 for slot 5 - I do it automatically via an exposed variable in the 2nd pic; you can do it manually since it's only 6 slots. Or you can run ForEach loop off the AllSlots array.

If in doubt, post a screenshot, perhaps I can poke holes in it.

avatar image Arro-Wing May 27 '19 at 09:49 PM

This is getting so unbelievably frustrating...

This is the only connected thing in the event graph of my slot widget. My images and text are set to derive their color from a binding that checks, among other things, whether or not this "Is Selected" Boolean is true or false.

alt text

This is the first thing in the event graph of my Player Inventory widget. I removed my previous setup and redid it to match yours aside from the testing-related stuff.

alt text

Everything seems to work so far. This is my OnMouseWheel override function. Literally copied one-to-one from your example.

alt text

And last but not least, here is my iteration stuff which I'm pretty sure is the exact same as yours.

alt text

I scroll my mouse both ways, and literally nothing seems to change. I can't even get a print string to spit out a line to confirm that something is happening. This project is making me want to cry so bad right now. :')

inventory-4.png (29.8 kB)
inventory-5.png (102.9 kB)
inventory-6.png (78.9 kB)
inventory-7.png (241.3 kB)
avatar image Everynone May 28 '19 at 06:31 AM

This project is making me want to cry so bad right now. :')

Ah, welcome to blueprint scripting. It all looks good at a glance.

I can't even get a print string to spit out a line to confirm that something is happening.

Let's focus on on printing the string first. I'll assume that you create and add the widget to the viewport. and the Input Mode is not set to Game Only.

It should start working as soon as you navigate to it and click inside it - this puts the widget in focus so it can start intercepting input before the Player Controller get its chance.

Let me know if this works and mouse scroll prints.

avatar image Arro-Wing Jun 03 '19 at 11:09 PM

For adding the HUD to the viewport, my "On Begin Play" in my character's BP is set to create the HUD widget as the very first thing and add it to the viewport. I don't have any sort of input mode setting.

This might be one of my problems with following your example: my HUD is not meant to be directly interacted with by the player aside from scrolling through inventory slots (which automatically draws the item in the selected slot without requiring any clicking). The scroll wheel doesn't control anything else in the game unless the player is in a menu screen.

avatar image Everynone Jun 04 '19 at 07:34 AM

I don't have any sort of input mode setting.

That'e fine.

This might be one of my problems with following your example: my HUD is not meant to be directly interacted with by the player aside from scrolling through inventory slots (which automatically draws the item in the selected slot without requiring any clicking).

I see, we can work around this easily, the input is currently implemented in the widget itself; when you interact with the game world, the widget will not have focus and not receive the scroll. Thanks for clarifying this.

For now (to test), can you just ensure that the root of the widget is Visible, click anywhere on the widget and use the scroll wheel. That should work. See if the scroll events print.

Regarding the lack of interactivity with this menu, rather than overriding onMouseWheel in the widget, move this functionality to the player controller and have it call the widget's custom event.

avatar image Arro-Wing Jun 05 '19 at 12:58 AM

Okay, so some good things happened and some bad things happened.

As you suggested, I moved the Mouse Wheel override over to the event graph of my Player Controller and connected it up to my Inventory Scroll axis mapping event (and deleted it from my Inventory widget).

alt text

I successfully got strings to print from this. However, I also got errors.

alt text

My Mouse Scrolled event is still in my Inventory widget's event graph, exactly where it was before and still an exact copy of yours.

inventory-8.png (105.0 kB)
inventory-9.png (16.5 kB)
avatar image Everynone Jun 05 '19 at 11:20 AM

You never set a reference to the SurvivorHUD, it seems. Creating a variable is just that, it holds no value. Imagine an int variable but it has no value (not even 0!).

You can either create the widget in the controller and Set SurvivorHUD, or have the blueprint that creates the widget cast to the Player Controller set the SurvivorHUD - this variable has to point at a valid object.

avatar image Arro-Wing Jun 06 '19 at 12:10 AM

I thought I did, but apparently not. Anyway, that did it! My inventory finally scrolls and highlights like I want! It's a beautiful sight to behold. LOL

I can't thank you enough for how patient and informative you've been. I sincerely appreciate your help.

Edit: Well, one last question. How to do the opposite scroll direction? I'm trying to figure that one out myself, but not having any luck.

avatar image Everynone Jun 06 '19 at 09:08 AM

Haha, wicked! One hurdle out of the way, more to come.

Well, one last question. How to do the opposite scroll direction? I'm trying to figure that one out myself, but not having any luck.

I'll have a look at it later. May not be today, though.

avatar image Everynone Jun 06 '19 at 12:51 PM

How to do the opposite scroll direction?

alt text

The top bit is for mouse scroll up. I tested it very briefly but it seemed to work fine, regardless of slot count. Do tell if it acts up.

Image from Gyazo

capture.png (498.7 kB)
avatar image Arro-Wing Jun 06 '19 at 10:53 PM

It seems to be working perfectly! Thank you so much!

avatar image Arro-Wing Jun 13 '19 at 12:48 AM

Now I'm working on adding functionality for picking up items in game and updating the HUD accordingly, and it seems that the scroll function isn't updating when new slots become available. The slot itself updates as desired, but I can't scroll to the newly-enabled slot. I've even got a function that sets the selected slot manually to the new item upon picking it up, and while my print string tells me that the new slot is being selected, the slot doesn't change to the appropriate color and any scrolling afterwards continues to treat the slot like it's still disabled and skips over it.

avatar image Everynone Jun 13 '19 at 07:12 AM

Technically, the whole system only cares about a single variable - the bool isEmpty. When you populate the slot, make sure you update the value. If a slot is occupied, its isEmpty should be set to False.

avatar image Arro-Wing Jun 13 '19 at 10:58 PM

That's what I was trying to update, but it looks like I was overthinking the whole thing and ended up with unnecessarily convoluted blueprints. I've gone back and done some messing around and got it to work. Thank you!

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question