Different functions in the same blueprint giving different variables?

I’m a super beginner using tutorials to try to piece together an inventory system. Since I’m kind of just following directions, I might not know the proper terminology so apologies in advance!

I’m currently on part 6 of this tutorial series and am running into an issue when trying to remove items from a map… at least I think they’re called maps.

This is the function I’m using to add items to my inventory system. Just a name/integer variable. It works fine for what I want, just a super basic ‘item x 1’ type of layout.

And here’s the function I’m using to remove items, in the same blueprint.


Unfortunately, the quantity from the find node always returns 0. If I fiddle with it a bit to force it to subtract, it dips into the negatives and keeps going. It’s keeping track of a number, just not the right one.

I’ve added a print string to return the number of a certain item and it’s always correct, but the remove items function seems like it has a separate list that it’s pulling from somehow. Unfortunately my limited knowledge has only let me find out where things are going wrong but I don’t know enough to know why! Any suggestions would be appreciated!

1 Like

In the second image you are passing Item Name and Quantity in to the function. Yet through out the function you aren’t using those Pinned values… You’re using variables. If those variables are “Local Function Variables” their values are NULL/EMPTY.

Either pipe the pinned passed values or set those pin values to local function vars as step one.

e.g. Remove Item Inventory: Set “Item Name” → Set “Quantity” → then use the local vars through out the function logic.

1 Like

I just tried throwing Item Name and Quantity into local variables and using those instead, but it unfortunately had the same problem.

After a little digging I found that “Item Name” and “Quantity” are correct coming out and it’s the “Find” node that’s messing things up, I think. So I’m getting the right Item Name, but when it goes into the “Find” node it’s not finding a match even though I can see I have two of them with a quick print string.

I am not going trough this code. However you should not create such spaghetti code.

Use those:

  • macros. When you have piece of code working and you are positive it does what you need, and it has no errors, collapse it to macro.
  • use “pure functions” same as above, but you can calculate some value, expose result, and use that function in rest of code. Even create blueprint function library and store such functions there (however do not make more than one library, it is easy to create circular dependencies).
  • create ENUMERATORS, compare them instead strings in code. You also can make pure function that returns enumerator based on tags, strings etc. Later there will be only single code (in that function) that needs to be upgraded if you decide to store all items in database etc.
  • use data structures
  • make your blueprint graph more readable.
  • do not drag multiple connections from return value of some node to other nodes. It is more readable if you use local variable, save value there and then read from this variable

You should confirm returned bool value of “Find”.Maybe value is “false”.

  • Use local vars to reduce pipe spaghetti.
  • Use Sequence node(s) to help organize. Technically not needed here, but it helps new devs.
  • Keep your conditional steps simple, yet efficient. Too the point.

This all looks like a job for pass-by-ref. @Rev0verDrive - don’t function inputs create local variables automagically already?

image

If only…

That might also stop the craze ( no doubt from utube ) of using functions to get things done ( ie, where you should be using a custom event ).

1 Like

Like I say, Tick should not be available until you have been using the engine for 6-8 months…

Mhm.

:smiley:

Apologies for the spaghetti code! I was just following a tutorial that seemed easy enough on Youtube, so I guess I didn’t think it was THAT bad. Buuut the problem with using tutorials is there’s no real way to know if you actually understand the subject matter besides screwing it up/have something break and not know what’s causing it.

So I guess my plan from here is to drop the project and come back to it later after I have a bit more understanding. Though, these replies have raised a few more questions!

  • When should I use functions over events? These are functions because they’re called in different blueprints that all give different variables. I just assumed functions could be called in separate blueprints while events couldn’t. Although to be fair exactly what allows blueprints to communicate with each other is still a bit of a mystery.

  • @zblogin mentioned the bool value of “Find”. That did come back false. Why would it though? This is the main issue I was having: I can see that it’s looking in Inventory Content for “ITEMX” and I know for a fact that I have 2 "ITEMX"s in my Inventory Content, but it still is showing up false.

I guess that’s it! Sorry if it’s asking too much, I just figured I’d get clearer answers here than looking up more tutorials. Thanks for all the tips so far, I’ll definitely give all this stuff a look over. And I’ll work on making blueprints more readable!

I’m just another newbie here, and from what I’ve understood functions are best practices if you have a repetative process or similar stuff going on.
For example for any kind of ‘Press E to…’ it’s better to have a function, than an event, so you can make ‘Press E to equip’ , ‘Press E to open door’, ‘Press E to turn on light’ .

Events should be something much more simplier or at least something that is done once.
But to advocate youtube classes, I can say working with Events and creating spaghetti is easier for understanding))

Just to be clear, I wasn’t talking about your code. It was just a general comment :slight_smile:

Keep going. Was not talking about your stuff…

Basically, if you have to do something - event. If you need to compute something and get a value back - function. Functions are used to DEATH on utube, where they are doing the job of a custom event. You can reach functions remotely just like custom events, it’s not really anything to do with that.

Also, if the function makes changes and gives a value back, technically it needs an execution path ( in and out connectors ), and if it just figures something out, it can be ‘pure’

which means you can use it like this

image

Checking the inventory: GREAT example of when to use a function. You give it the name, and it gives you back a bool :slight_smile:

  • you can call both Events and Functions in other blueprints
  • you want data returned (success?), use a function, as you do
  • you want data returned without modifying anything, use a pure function
  • you want to hook up an Event Dispatcher, → Event or Function but none can return data here
  • you need to operate on local variables and stuff will, inevitably, become a tangled wire spaghetti → function(s)
  • you want to use a Latent action (Delay, Timeline, Animations with a Finished Event), use an Event
  • you want replication → Events
  • the way Functions and Events handle passing by reference in BPs is different (long story)
  • Events can take a loooot of space in the graph but you can always have many graphs to organise things better:

image

There are also Macros, and Collapsed Graphs. :innocent:

Although to be fair exactly what allows blueprints to communicate with each other is still a bit of a mystery.

References. When a blueprint is instantiated (spawned), it becomes an actor. We can store its reference in a variable (where it sits in memory and what it is - the address) in order to access its member functions, events and variables.

image

It’s a matter of telling one actor where (and what) the other actor is. The actor with the script above will now know where the newly spawned one is and we can use that New Var 0 reference variable to access it.

You’ll see references used throughout blueprints, while in C++ you’ll be also using pointers.


Unfortunately, the quantity from the find node always returns 0

More than suspicious. Are we 100% sure that we actually do Find the Name. Find returns True | False - can you check?

Yup!
All Parameters/Arguments specified in the declaration are accessible variables in the function definition (body).

void Remove_From_Inventory(string ItemName, int Quantity) { // Declaration
    // Definition - executable code
}

This isn’t common knowledge to new devs. If you code sure, but if your intro is blueprints then not so much. They aren’t listed in the “Local variables” section in My Blueprint…not very intuitive to the new users. On that note, declaration is the reason you can’t name vars in the function to mirror the pinned names. Already defined.

When I do “Help posts” in BP I’ll promote inputs to locals manually. It helps promote cleaner Bp’s and you’re not getting questioned about where x var (declared) came from. They’ll learn declaration when they transition to C++.

I treat Events as the Initializer of some functionality. Each function has very specific functionality. 99% of which will eventually be translated to C++ when prototyping is done (low level stuff).

E pressed: → Validate → Role/Auth, Switch Has Auth → Custom Event
Custom Event: → func_Step1 → func_Step2 → Some other event if need be

Stick with it. Questions and failure is how you learn.

2 Likes