Monday, May 22, 2017

Tower Defense Starter Kit Tutorial: How to add custom Tower Abilities

[The following information is based on the v1.6.3 edition of Tower Defense Starter Kit & hence may not remain entirely relevant in later versions. For more information about the toolkit, check out the official support thread in the Unreal Engine forums:]

The Tower Defense Starter Kit features two Tower Abilities (Overdrive & Repair) than can be added to the towers in order to provide the player with an additional element of control over the gameplay. This tutorial will go over the steps involved in the creation of a new Tower Ability & it's integration with the existing system.

Before delving into the matter of actual implementation, I think it would be best to understand that there are generally two types of dynamically driven abilities: sustained abilities that modify the functioning of the targeted actor over a brief span of time, & momentary abilities that cause a certain change within the system for just an instant of time. Overdrive & Repair are sustained abilities & hence I would like to show the creation of a momentary Shockwave ability with this tutorial. 

1. Create a duplicate blueprint based off of the 'BPC_OverdriveAbility' class. This will provide you with a base template for the new ability without having to start from scratch. At this step of the tutorial, there is a slight difference based on which direction you want to take.

If you plan to create an ability with sustained effects, there is no need to make any changes to the default parameters right now.

On the other hand, if you want to have a momentary ability, then delete the following variables: RemainingTime, AbilityDurationDisplayUpdateTimer, AbilityDurationDisplayUpdateTimerInterval, AbilityStatusBarFillColor, & AbilityDuration. Also make sure to delete all instances of the ability duration timer within the component.

2. The next step is to modify the following text variables to suit the description of your new ability: AbilityName, AbilityNameAbrreviation, AbilityDescription, HUDStatName_CoreFunction, & HUDStatsName_LimitingFactor. These variables determine the information displayed about the ability in the HUD.

3. Now create the variables that would be required for the functioning of your Tower Ability. For example, I'm going to add a couple of float variables named 'ShockwaveDamage' & 'ShockwaveRadius' [see sample screenshot below]. For a very basic shockwave ability that does damage to all enemy units in it's range, that should be enough. For now, that's all there is do within the ability component class. We'll come back later to write down the actual implementation once the remaining factors are taken care of.

4. Open up the enum 'ETowerFunctions' & add a new entry with the name of your new Tower Ability.

5. Now that we have the new enum entry & component set up, you can add a new ability to the list maintained in the 'BP_GameInstance' blueprint. To do this, add a new element to the Tower Functions Array & make the following changes to the default values: set the 'FunctionType' as the new enum value, & the 'AbilityComponent' as the custom component; the 'AbilityCost' can be set to any arbitrary non-negative value; under the 'CompatibleTowers' list, add all towers that should be able to use the new ability; & set the 'Unlocked?' parameter to true.

Here is a sample screenshot for my Shockwave ability entry:

6. The next step is to integrate the new Tower Ability into the system through the 'BPI_TowerAbilities' interface. You will have to add new functions to handle the following cases: to add the new ability component to the tower actor, to activate the ability, & to deactivate the ability. The last two functions are only necessary of it's a sustained ability. If you check out the interface functions list, you will notice that both overdrive & repair abilities have these two functions to handle it's activation/deactivation. Since I'm creating a single fire ability, only the first function is required as shown below:

7. Now head over to the 'BP_Tower_Parent' blueprint & implement the newly created interface functions. In order to add an ability component, just copy the same code from the equivalent interface function for the overdrive ability & replace the Add Component node (check screenshot below) with the node to add the new Tower Ability component. With this function set up, you should be able to request a call to activate the ability from other classes that interact directly with the player. In case of sustained abilities, make sure to implement the Activate/Deactivate functions as well. Basically these functions are used to modify/reset any changes made to the Tower's attributes by the component. You can check out the implementation for Overdrive/Repair abilities as a reference, if there are any doubts.

8. Open the 'Widget_TowerFunctionsButton' class & call the previously added interface function for adding the custom ability component & connect it to the switch case output for the associated entry as shown below:

Also make the following changes within the 'UpdateTowerFunctionWidgetState' function:

With these connections set up, the player interactions with the tower function button for the new ability will be able to connect with the tower in order to pass on the request.

9. Before going into the implementation of the ability, there's one more thing to be taken care of & that is to add the code to display information about it through the stats UI element when the mouse hovers over the tower function button. This is handled through the 'GetTowerAbilityClassInformation' function in the 'Widget_TargetInformation' class. Just copy the nodes connected to the overdrive switch case, & paste it elsewhere. Now swap out the cast with a cast to your custom ability component & connect it to the corresponding switch case output as shown below:

10. The final step is to head back to the tower ability component & write down the actual implementation for your ability. In my case, I'm going to add an apply radial damage node & connect it to the begin play event to do damage to all enemy units around the tower.

With that, we've come to the end of the tutorial & you should have your own version of tower ability ready to go. If anyone has any doubts regarding the workflow, feel free to post in the comments section.