I did indeed forget to call Destroy on those actors, nice find! I’ll add this to my update list for the next pass on the tutorial.
Edit: Redoing it all from scratch, so this post is moot now.
I’ve finally got my inventory system working how I want, and it’s awesome. Thanks Tom for your tutorial!
I’m going to be polishing up what I have a little bit and then post it all back here, as I feel it gives a little bit more of the puzzle when doing a full on inventory system with different types of items. There are still a few things that need cleaning up in terms of how its structured and the portability of the code (right now I’m not casting from generic character in a bunch of places and the naming scheme is not good right now, so that will be changed).
That said, this is how it works now:
- Dropping is networked too.
- Picking up an item attaches the pickup actor mesh to a socket of your choice (eg., hand). Right now this has a neat zoooop effect where it hoovers into your hand (no extra code required for that - it just happened).
- Dropping drops from the hand you selected (and re-enables physics, which can be amusing when you kick your item as it falls).
- Pickup uses E (or whatever is bound to the base interact from the tutorial), then it has a Use/Equip function (also networked), using an interface (which btw does what you’d expect and calls up to the parent with the child params, which is great).
Right now, I only have food implemented. Here’s the inheritance scheme:
BP_UsableActor (base actor)
— BP_InventoryActor (holds a ref to the PickupActor, which is shown in the hand, and is used to call into the PickupActor’s use functionality, when it’s the selected item and LMB is clicked).
— BP_PickupActor (for actors that sit on the ground, and optionally have physics, also has the UseInterface).
------- BP_FoodActor (other types live at this level e.g., BP_WeaponActor), a PickupActor that restores hunger value. Implements the UseInterface function.
---------- BP_Meat, this is where my item level stuff lives, and where the hunger restore gets set, as well as the proper mesh for the item.
The key changes are the interface, misc changes about picking up/dropping from the socket, networking for dropping, and passing along the PickupActor into the InventoryActor directly rather than spawning it based on a class.
This allows having the PickupActor on the hand of the character, as well as (later for my purposes) an item system that is non-destructive when picking up/dropping, so that items that go into or out of the character inventory retain state, even when dropped.
The interface makes it so that implementing new types of items without cluttering the base blueprints is pretty easy (derive from PickupActor, implement the UseInterface, base your items off of that BP and customize the values in your instance).
Here is a guide to my modified inventory system. If you follow Tom’s original tutorial, you can simply make these modifications and you’ll have it working the same as I describe above.
(Beggar is my character BP class)
Character Event Graph:
Client/Server Pickup
Client/Server Drop
Client/Server Use
Attach Item Function
Modified AddItem
Modified DropItem
BP_InventoryActor:
UsePickup Function
Holds ref to PickupActor directly, rather than class.
BP_PickupActor:
Use Function
UseInterface:
I know this looks empty, but it’s right. A single function called OnPickupUsed.
Implementing UseInterface (BP_FoodActor is a child of BP_PickupActor):
That’s it! Just make new children of BP_PickupActor that implement the OnPickupUsed interface, and individual items as children of that.
Thanks again Tom for setting me on the right track.
Hey! Thanks for these additions!
The purpose of the tutorial was exactly that, providing a starting point for your own custom behavior on top I will add some additional steps in the original tutorial to make it easier to extend (using yours as an example of what needs to be modified)
Be careful with using “Get Player Character” though when building for networked games! OnPickupUsed should be executed on the server side where you cannot use any nodes that require a player index. You might want to pass a reference of the character that used the item as Input of the event.
I figured as much, but couldn’t figure out how to actually pass the character ref through such that the Event On Pickup Used will get the input. Seems like with the message system it doesn’t really work.
As an aside, the pickup logic doesn’t work in multiplayer either, though I’m not sure why (it attaches to the hand of the remote player on the listen server, but not on the remote client).
Edit: Got it (passing the character) working! I just had to refresh the node. Still not sure why the attachment doesn’t work correctly on remote clients.
Looking back over the networking w/ blueprint tutorials, it sounds like the system would need to use RepNotify in order to get the hand attachment to work on the remote client? Is that right?
Not exactly sure what the best way to set it up cleanly is. I’m going to go back over everything tonight and fix up things with authority guards and see what I can come up with. If you have any suggestions Tom, I’m all ears
RepNotify sounds like a good solution. This is how I solved updating weapon material glow on remote clients in Unreal 3.
Cool. I figure I can make the selected index a repnotify and base it on that, since it’s going to change when a player picks up an item or selects next/prev.
I ended up having it do repnotify on the pickup actor, since that’s what actually gets set right before attachment.
In any case, I got it working. In the notify event, I call attach and use the Get Player Character, since on the remote client it should only have the single player index. Works great!
One issue I did notice is that scaled actors are behaving oddly - on the server everything is normal, but on the client, every time the server picks up and drops an item, it gets smaller by whatever scale factor it already had. Not sure if there’s something in my BP that was left over from before or what.
In any case - using the items also works! And I fixed my hunger system to be mutliplayer compatible as well.
Edit: It’s necessary to have some way to repnotify the client about when to detach the object too. I made a bool with a separate repnotify.
Edit again: Figured out the scale issue - make sure to have Maintain World Position checked in all the places where things are detached.
I checked out the blueprint tutorial on Toms website very nice work. I did notice though that if you are in a client listen server the drop command is not working on the client side. Client can pickup but not drop so there is a replication call missing somewhere in that setup. I have not attempted to fix it just wondering if anyone had this and perhaps I missed a step.
Thanks for letting me know. I’ll see if I get the same issue, and will update if I have a fix.
I was able to reproduce the issue on the client, I submitted a fix in the comments - I will integrate the changes into the tutorial whenever I get the time. Thanks for pointing this out!
So I narrowed it down to the AddItem not being fired in the character blueprint so the item is not added to the array. Not sure as to why this is happening but the EventOnUsed is working but the casttocharacter is not calling the additem function except on the server if in a listen/client and not at all if on dedicated server.
You submitted a fix in the comments but I could not locate it sorry.
Turns out that fix was for the C++ variation, I mixed those two up! I’ll do a review pass on the released tutorials soon to implement all the feedback I received.
I’ll dig through the project and see if what is required for multiplayer support (that was not in the scope of the original inventory part 2 tutorial)
If your cast if failing you could add a “Print String” node to the “Cast Failed” output node of your character cast, this may help since you are seeing issues with AddItem not being called right after you cast?
Hi, I was stucked like you and also I tried to add a mesh in the child BP, but looks like the behavior of the raycast doesn’t work perfect at this way…
Make sure to pay close attention to what class each blueprint is parented from - the one with a static mesh needs to have StaticMeshActor as the parent. Having it as a separate component on a normal Actor-derived blueprint causes problems later.
Please, fix me if I’m wrong…
a) I’ve created the base “BP_UsableActor” as Actor BP, then add in it a static mesh and design the focuses and onuse functions.
b) Create the “BP_PickupActor” based on “BP_UsableActor”, then add a static mesh component in it.
I haven’t realized the way to replace the base mesh, so the mesh of BP_UsableActor envolve the BP_UsableActor one, if set “None” the mesh in Base one, the mesh looks fine and the highlightning but the raycast doesn’t works properly
Remove the static mesh component from BP_UsableActor and the others as well, and rebase BP_UsableActor on StaticMeshActor.
Ok, never mind, the problem was in the raycast, thank you mate for your time