Collecting resources

I'm finally back to programming after some time spent with 3D modeling, printing and a hard disk failure that forced me to re-install everything, including Unreal Engine and Visual Studio, with all the troubles of importing the project in a new environemnt (I tried to switch to VS 2017 and UE 4.17, but I reverted back to VS 2015 and UE 4.15 after several compilation fails).

And the next thing I'm going to handle is the raw material for building our mines and for repairing the spaceship: collecting resources!

To display and manage resources we're going to use many techniques we already used for enemies. It's actually even simpler, because a resource will spawn at a location and never move until it's collected from either the player or an enemy.

As a first step, I imported the asset I created in Blender (my floating potatoes):



Then I created a C++ class named "ResourceClass", and I derived a Blueprint Class from it so we can easily add multiple visual assets and check overlapping (as we did in this post).

In the Blueprint editor, I can add the 3D asset by clicking Add Component > Static Mesh:


Remember to check if "Generate Overlap Events" is checked in the details panel.

I want the resources to slowly rotate around their axis when theyre on screen, so I will write a simple tick() method in the class code:



This will set the Rotation of the actor each frame, adding a small quantity based on the milliseconds between one frame and another, giving the illusion of movement.

Son't forget to set the bActorCanTick variable to true in the constructor, or the tick() method will never be called!

Now, if we drag the MyResourceBP icon in the game editor and press Play, we can already see the small rocks rotating.

Obviously, we don't want to drag the items inside the editor, because we need to programatically spawn them from code; so let's move to MyController class and do the preliminary work to achieve that goal.

We need a pointer to the Subclass of Resource:



Then we can spawn the Resource, and add it to its own array:



Next, I created a Blueprint callable hit() method and I chained it to the OnBeginOverlap event inside the Blueprint editor:



Now, what should we do in case we hit the resource? If it's hit by an enemy, we simply need to destroy it, but if it's hit by the player, we need to increase its number of collected resources. So here's the complete hit() method:



It uses the method GetPlayerShip() of  the MyController class, that simply returns a pointer to the Player object. It's confronted with the other pointer, and if they're the same object I perform the appropriate logic.

The addResources() method of the controller will add 1 resource to the counter and redraw the user interface. Here's the code:



One thing to remember is that in case of collision between a resource and an enemy, when the overlapping event is fired for the resource, it's also fired for the enemy ship, and we need to be sure that the event isn't handled twice, so let's check the hit() event of the EnemyClass:




In this case I don't have a single object to check against the other pointer returned by the Hit() method, and I don't want to iterate over the ResourcesList array each time a collision occurs. So I simply check other's class against the resourceClass stored inside the controller object, which is exactly the Blueprint class of our resources.

In case the enemy ship collides with a resource, the latter should be consumed but the ship shouldn't be destroyed, and it shouldn't trigger neither the explosion effect nor the camera shake. Since the 2 actions are performed inside the blueprint of the EnemyShipBP class whenever a collision is detected, I will modify it to check if the destroy flag of the ship is set to true, using a branch box:





In the MyController class we need to manage the destruction of objects inside the array (the code below is added to the DestroyItems() method:



Now it's time to handle the visibility of the resource. We can do a simple check when the resource is spawned to decide its initial state, and another check when the player ship moves, since it's the only moment when a tile changes its state:

Here's the modified part inside the Tick() method:


And the body of the checkResourcesVisibility() method:



Great, with few steps we have fully working (and rotating!) resources; next time we can think about using them, activating the buttons on the User Interface.



I wish you all a happy new year, and don't forget to subscribe to my Youtube channel, in this playlist I'm going to keep track of the progress made in the project:

Youtube Videogame Discovery Playlist

Commenti