Around the 22:00 mark when I'm testing the final implementation, I mentioned there's a bug with displaying the items in the inventory... not really crucial to the lesson, but if anyone is curious, the "bug" was just that I forgot to make a call to the ClearChildren() function in the Inventory RefreshInventory() function, so it was creating duplicates of every item each time RefreshInventory() was called.
Something I found useful after spending hours fault finding because I made the c++ class the reference instead of the WBP BP class you set in BPs, making the c++ class abstract by adding UCLASS(Abstract) will stop it from showing up as a selectable option. Thanks for the vid.
Thanks for the tip. At first it seemed a bit weird to wrap my head around, but I suppose the proper way I should think of it is that the UCLASS abstract specifier applies toward blueprint, not from the C++ class toward other C++ classes. So it becomes abstract from the context of the editor, but can still contain implementations and non-virtual functions on the C++ side of things.
@@GeorgePence True, I never noticed that I guess the UCLASS is purely a editor api type link from your code like UPROPERTY and UFUNCTION and all that is the way I understand those unreal specific additions. To make a c++ class abstract it would need to contain an abstract function I believe. Look out learning more!
Dude I am definately the same writing everything in c++. Unreal is a bit tricky with c++ as you are still operating on a layer above communicating with the engine.
This is quality content. Thank you so much. I was wondering where did you learn this from and if there are resources can you point me that way? Thx. The info regarding this topic is so scarce
There's no easy way to learn the knowledge... I majored in Computer Engineering in school, and have worked since college with C++ at my day job. For UE4 it's just been tons of studying documentation, tutorials, and examining the source code. You just have to accept that it's a long journey and take it a day at a time.
Might be a stupid question but I'll still ask: At 10:24, you're using GetOwningPlayerPawn() to get a reference to the character. The docs tells me that it returns the owning pawn of this widget but what does it mean? When is this owning relation created/set ? Is it something that the UserWidget class does (Binding all the classes that inhertis it to wichever pawn we're possessing) or is it because for another reason ?
It's not stupid at all. I have thought about this same thing myself. If you look in the UserWidget class, there is a field called "FLocalPlayerContext PlayerContext". LocalPlayerContext is a special engine struct used to store info about the player the widget is associated with. Down in UserWidget.cpp there is a function called CreateInstanceInternal, which is called by CreateWidgetInstance, and if you look at the arguments you will see one of them is "GameInstance.GetFirstGamePlayer()". They then call NewWidget->SetPlayerContext() inside of CreateInstanceInternal and give it that argument. This PlayerContext variable is what is then retrieved when you call GetOwningPlayerPawn on a widget. So it's really just that you are obtaining whoever is designated as player 1 by the game instance. In a single player game it's obvious who that is, whereas in a multiplayer game, it's the "local player", of which there should only be one, you who is playing as the client. So I know that is a bit convoluted, but it's because it's a lot of engine stuff we aren't normally exposed to that runs automatically in the background.
@@GeorgePence Thanks a lot man. I really appreciate CZcamsrs that take time to answer questions. I don't know about the future of the channel but let me tell you that Unreal people that are doing C++ tutorial are invaluable treasures. So that lets you know what I think of C++ UI stuff.
Thank you so much, this is very informative! I know this is old but what is the difference between NativeOnInitialized and a regular constructor? I'm not a hardcore programmer, I tried to google it, but pretty hard to comprehend.
The difference I have learned over time is that there is an actual constructor that gets called on a lower level to actually create the underlying Slate and UMG framework, but for the actual "user" portion of your UserWidget, NativeOnInitialized is used. There is also NativeConstruct which functions more similarly to a regular constructor, but again the TRUE constructor is abstracted away from us when working on widgets. The main reason is that you don't need to worry about the engine level stuff, you just care about adding variables and functions to your widget, so they sort of separated the logic, if that makes sense. But all that to say, if you stick with NativeOnInitialized you should be fine!
Wow did not expect to get an answer from you so soon. Thank you very much! So I guess, in layman's term, when dealing with UI just use NativeOnInitialized in place of a constructor? If that is, then I now understand lol @@GeorgePence
Do you have any info what you included in the Inventorycomponent and how it was setup? (In case it included anything else than just being a placeholder piggybacked on the player). Do you have any tips how to override mouse drag and drop functionality in between widgets in C++ ? typically like dragging objects between inventoriy widgets or from an Inventory into the world( dropping things ) Otherwise much appreciated the video and very useful stuff here Thanks and Cheers
Hey there. The InventoryComponent was a modified version of the one Reuben Ward shows in his Survival Game Course, but essentially it's nothing but a component that can be put on any Actor consisting of an array with a lot of functions that manage checking for quantities and whether or not an item should be stackable. As far as drag and drop, I have overridden it in pure C++ before, and I'd like to make a tutorial on it. It consists of using the UUserWidget functions NativeOnDragDetected and NativeOnMouseButtonDown.
@@GeorgePenceThanks, it's a pity you don't reveal the full setup to get it working. Figuring out what you changed in the component with all serverside stuff Reuben added that first needs to be removed is a few days work on it own. Adding the cpp and header file to a respository would help a lot. Cheers
@@deluxepopper Haha, mostly I just removed all the replication and then cleaned things up on my own. Are you on Reuben's server? You can find me there as Zaelus and I can send you the info.
@@GeorgePence Haha.. Dr Z?.. Who would have known :) Yeah then you know who i am.. The guy with the white hat.. I never really got past his course because the copy & paste stuff where something got messed up somewhere at 60% finished, then i just got so fed up and ended my Patreon.. Did you really get that survival working in the end? I'll send a PM later.. would be great to see the component cleaned and save a little bit of headache.. Cheers
Hi George, great tutorial! Maybe you can help me with a simple problem. I'm trying to read an EditableTextBox in C++: My code: UPROPERTY(BlueprintReadWrite, meta = (BindWidget)) class UEditableTextBox* YearTextBox; But in Blueprints I get: A required widget binding "YearTextBox" of type Text Box was not found. How do I fix this? Thanks, Dwight
Hey there, that usually means that you just need to have that text box created in your widget blue print and name it the exact same as the C++ code version. Then when you recompile your widget blueprint, if you have parented it to the C++ class correctly, that error should go away.
Around the 22:00 mark when I'm testing the final implementation, I mentioned there's a bug with displaying the items in the inventory... not really crucial to the lesson, but if anyone is curious, the "bug" was just that I forgot to make a call to the ClearChildren() function in the Inventory RefreshInventory() function, so it was creating duplicates of every item each time RefreshInventory() was called.
Thank you so much! So few people go over c++ in depth in Unreal engine
Glad to help!
Something I found useful after spending hours fault finding because I made the c++ class the reference instead of the WBP BP class you set in BPs, making the c++ class abstract by adding UCLASS(Abstract) will stop it from showing up as a selectable option. Thanks for the vid.
Thanks for the tip. At first it seemed a bit weird to wrap my head around, but I suppose the proper way I should think of it is that the UCLASS abstract specifier applies toward blueprint, not from the C++ class toward other C++ classes. So it becomes abstract from the context of the editor, but can still contain implementations and non-virtual functions on the C++ side of things.
@@GeorgePence True, I never noticed that I guess the UCLASS is purely a editor api type link from your code like UPROPERTY and UFUNCTION and all that is the way I understand those unreal specific additions. To make a c++ class abstract it would need to contain an abstract function I believe. Look out learning more!
Great work dude. It's hard to find like these kind of guides.
Man, you are a Life Saver! Thank you so much!
Great C++ tutorial !!!
That was very useful thank you so much and keep up the good work
Thanks so much for this clear explanation !
Dude I am definately the same writing everything in c++. Unreal is a bit tricky with c++ as you are still operating on a layer above communicating with the engine.
Thank you!
This is quality content. Thank you so much. I was wondering where did you learn this from and if there are resources can you point me that way? Thx. The info regarding this topic is so scarce
There's no easy way to learn the knowledge... I majored in Computer Engineering in school, and have worked since college with C++ at my day job. For UE4 it's just been tons of studying documentation, tutorials, and examining the source code. You just have to accept that it's a long journey and take it a day at a time.
Might be a stupid question but I'll still ask: At 10:24, you're using GetOwningPlayerPawn() to get a reference to the character. The docs tells me that it returns the owning pawn of this widget but what does it mean? When is this owning relation created/set ? Is it something that the UserWidget class does (Binding all the classes that inhertis it to wichever pawn we're possessing) or is it because for another reason ?
It's not stupid at all. I have thought about this same thing myself. If you look in the UserWidget class, there is a field called "FLocalPlayerContext PlayerContext". LocalPlayerContext is a special engine struct used to store info about the player the widget is associated with. Down in UserWidget.cpp there is a function called CreateInstanceInternal, which is called by CreateWidgetInstance, and if you look at the arguments you will see one of them is "GameInstance.GetFirstGamePlayer()". They then call NewWidget->SetPlayerContext() inside of CreateInstanceInternal and give it that argument.
This PlayerContext variable is what is then retrieved when you call GetOwningPlayerPawn on a widget. So it's really just that you are obtaining whoever is designated as player 1 by the game instance. In a single player game it's obvious who that is, whereas in a multiplayer game, it's the "local player", of which there should only be one, you who is playing as the client.
So I know that is a bit convoluted, but it's because it's a lot of engine stuff we aren't normally exposed to that runs automatically in the background.
@@GeorgePence Thanks a lot man. I really appreciate CZcamsrs that take time to answer questions.
I don't know about the future of the channel but let me tell you that Unreal people that are doing C++ tutorial are invaluable treasures. So that lets you know what I think of C++ UI stuff.
Thank you so much, this is very informative! I know this is old but what is the difference between NativeOnInitialized and a regular constructor? I'm not a hardcore programmer, I tried to google it, but pretty hard to comprehend.
The difference I have learned over time is that there is an actual constructor that gets called on a lower level to actually create the underlying Slate and UMG framework, but for the actual "user" portion of your UserWidget, NativeOnInitialized is used. There is also NativeConstruct which functions more similarly to a regular constructor, but again the TRUE constructor is abstracted away from us when working on widgets. The main reason is that you don't need to worry about the engine level stuff, you just care about adding variables and functions to your widget, so they sort of separated the logic, if that makes sense. But all that to say, if you stick with NativeOnInitialized you should be fine!
Wow did not expect to get an answer from you so soon. Thank you very much! So I guess, in layman's term, when dealing with UI just use NativeOnInitialized in place of a constructor? If that is, then I now understand lol @@GeorgePence
@@GeuGeuStudio Yup, that's correct.
Do you have any info what you included in the Inventorycomponent and how it was setup? (In case it included anything else than just being a placeholder piggybacked on the player).
Do you have any tips how to override mouse drag and drop functionality in between widgets in C++ ? typically like dragging objects between inventoriy widgets or from an Inventory into the world( dropping things ) Otherwise much appreciated the video and very useful stuff here
Thanks and Cheers
Hey there. The InventoryComponent was a modified version of the one Reuben Ward shows in his Survival Game Course, but essentially it's nothing but a component that can be put on any Actor consisting of an array with a lot of functions that manage checking for quantities and whether or not an item should be stackable. As far as drag and drop, I have overridden it in pure C++ before, and I'd like to make a tutorial on it. It consists of using the UUserWidget functions NativeOnDragDetected and NativeOnMouseButtonDown.
@@GeorgePenceThanks, it's a pity you don't reveal the full setup to get it working. Figuring out what you changed in the component with all serverside stuff Reuben added that first needs to be removed is a few days work on it own. Adding the cpp and header file to a respository would help a lot. Cheers
@@deluxepopper Haha, mostly I just removed all the replication and then cleaned things up on my own. Are you on Reuben's server? You can find me there as Zaelus and I can send you the info.
@@GeorgePence Haha.. Dr Z?.. Who would have known :) Yeah then you know who i am.. The guy with the white hat.. I never really got past his course because the copy & paste stuff where something got messed up somewhere at 60% finished, then i just got so fed up and ended my Patreon.. Did you really get that survival working in the end? I'll send a PM later.. would be great to see the component cleaned and save a little bit of headache.. Cheers
Hi George, great tutorial! Maybe you can help me with a simple problem. I'm trying to read an EditableTextBox in C++: My code:
UPROPERTY(BlueprintReadWrite, meta = (BindWidget))
class UEditableTextBox* YearTextBox;
But in Blueprints I get:
A required widget binding "YearTextBox" of type Text Box was not found.
How do I fix this?
Thanks, Dwight
Never mind, it turned out to be a header file problem. Got it working, Thanks.
Hey there, that usually means that you just need to have that text box created in your widget blue print and name it the exact same as the C++ code version. Then when you recompile your widget blueprint, if you have parented it to the C++ class correctly, that error should go away.
Font is weird, hard to see 😳😳
lol make the video fullscreen... nobody else has ever had an issue with it. Although, I do use a different font nowadays for my videos.