With the recent changes to my employment, one of the things I've been so happy about is being able to publicly talk about my personal projects again. And with the last 4 years of my work being in Unreal, I've gotten to get a lot of experience there. So I thought what better way to christen my return to development blogs than with a small project in Unreal Engine 5.
Where It Started
One of my favorite pieces of knowledge I picked up in Unreal has been the Child-Parent Relation. This has saved me so much time while I'm building new blueprints, and is even something I passed along to a few of my friends. And in doing that, I decided to take it a little further and build a collectable system in the 3rd person template.
How It Works
So each collectable draws from a parent class that I set up, which is pretty simple. First, we set up some basic rotation on every tick and give the parent a static mesh component. After that, we set up some basic collision so that whenever our player character runs into a collectable, it triggers the custom event that we set up on each child.
A little extra piece I added was a public bool that when false, will destroy the collectable upon being collected. But if it's set to true, we disable the collision, hide the static mesh, and then set a timer that can also be adjusted publicly. Once the timer finishes, we turn everything back on, and the player can grab the collectable again. More details are in the screenshots below. There's also a little extra something in there that I'll talk about a little later.
Building The Children
So now that we have the parent class set up, we can use it to build our children. Like I said before, we have a custom event on the parent that we can now set up on the children to have them do different things. And as we saw in that first gif, I put together three children that can each do different things. And for each one, I modeled a geometry for each one, and then converted it to a static mesh to use.
Coins
I started out simple with the first one by making a coin you could pick up that adds money to a player's inventory. And with that being a new concept for the 3rd Person Character, I needed to make some modifications there as well. So I set up a new structure to apply to the player character as a new variable. This way, I could build an inventory system that more easily keeps track of variables than just applying them to the BP, and makes them all easy to access when needed. After that, it was as simple as setting up a public integer for the value of a coin, and each time it's collected, we add that value to the money in the inventory.
Speed Boost
Keeping to using basic numbers, I wanted to see if I could make a simple speed boost that lasts for a couple seconds. It turned out being a little different than I expected though, cause most of the logic wound up being on the player character instead of the collectable. Ultimately, it gives us a bit more freedom with adjusting the character stats if we wanted to do so outside of our collectables.
When the player collects a speed boost, we trigger a custom event on the character, which also asks us to plug in how much of a boost you get, and how long the boost lasts. From there, it moves to the player character, who plugs the amount of boost into a macro that can either increase or decrease the speed, and then the amount of time into a timer we set by function that will turn the boost off once we run out.
Keys & Unlockables
Now this is where things get fun; making a key that adds to the inventory was pretty easy, so as a bonus, I made a door and a treasure chest that open when you have the right key. We start out with a parent class that can be used for any interactable, so this way, we can make more than just something you can unlock. If the player is within the trigger zone for an interactable, it will assign itself to the player. This way, only that interactable responds when the player presses the interact button. And once they do that, the custom interact event will be triggered.
On the unlockable child, we do a check of the player's inventory against a public variable the that represents the key that opens the unlockable. If we get a match, we take that key out of the player's inventory, and the custom open event gets called. This is where we can start making children for the unlockable.
Treasure Chest
The treasure chest is a bit of an interesting one; first we create another new structure to represent the actual treasure inside, which can be a mix of money and items. Once we have that, we check to see if the chest has already been opened, and if it hasn't, we grant them the money we assign to the chest (similar logic to what we use for the coins). On top of that we also add items to the player's inventory, which has a little extra functionality. These items are an array of assets that are in the scene and use that I mentioned earlier for the collectables. Since we can't instantiate the collectables, we put a public bool on them to say if they're in a chest or not. If they are, we simply turn of their collision and hide them. Getting back to the inventory, we set up a for each loop to see if any of the items are a key or not, and if they are, we separate them in the player's inventory.
Doors
And then we have doors. These are pretty straightforward where we get the location of the door in the scene on begin play. Then over the course of a timeline, we lerp the door from the starting location to the open location (this is a public vector that we can assign values for). This was, we can get a really smooth look when the door open.
Conclusions
Getting to finally show off my new skills in Unreal 5 and Blueprints was so much fun, and I think the collectables came out really well. Using the child-parent relation made them pretty universal to set up, and if I were to put more time into this project, I think I could make a bunch of other really cool ones. With that said, I'm actually already applying some of these ideas to a new prototype for a group project I'm working on. More details on that will be coming at some point, but on the whole, each of these features were so much fun and reminded me how satisfying it is to set up game features.
If I had to do one thing to expand on these, I would want to explore making a flushed out level with them to build my level design skills more. Who knows, if I come up with some more ideas, maybe we can make that a reality with this new project!
Opmerkingen