Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

"Why Doesn't It Work?" - Luke Cardelli | 15 September 2023

The Problem

This week I tried getting clever by half and begin to introduce enums and interfaces to my enemy system. Enums would be used to check and/or update the players state/ movement speed and the interfaces would be used to consolidate function signatures. I didn't want to necessarily override functions, I just needed a way to call the same function but have a different implementation. In theory, this should have been an easy task to implement… it was not.

For context, I am currently converting a blueprint enemy prototype to code. In doing so, I have learned that Unreal blueprints do not natively convert to C++. For the purposes of this post, I will illustrate the issues I was experiencing a using a specific example. I needed an interface that would have the SetMovement() function that could then be called by several BT Node Tasks. Easy enough, no? On paper yes but having spent little time working with interfaces in code, I was plagued with red squiggly lines and compile errors while attempting to implement said name thing.

Sometimes the code would compile, and I would hold my breath as I hit the play button only to be disappointed as my avatar would get locked in T-Pose. Other times, everything appeared to be working except the sword wouldn’t spawn. Agnostic to my best efforts, I couldn’t crack the nut regarding this interface and BT Task Node implementation. It’s only when   we become desperate do we unwittingly scrape the bottom of the barrel and discover the oh so simple solution.


 <Reference Image of the model going T-Pose>


<Reference Image of the enemy  attacking the player without the sword spawning>

The Solution

With interfaces, it is important to note that whatever class is deriving from the interface needs to have their own function signature. That’s how it works, right? The interface creates the function signature, and then your other class generates the same signature but then adds the logic. In this case, my EnemyBase was using the interface function SetMovementSpeed(), so naturally I created the signature in the header file and then added the logic to the .cpp. Where things get interesting is with my BT Task Node.

I created a BT Task Node called SetMovementSpeed. The node takes an enemy reference and attempts to call the EnemyBase’s SetMovementSpeed(), just like how you would call any other EnemyBase function. For whatever reason though, visual studio didn’t like this. As alluded to earlier, if a class is calling a function from an interface, they need to first create the signature. On my BT Task Node, I was not deriving from the interface, nor had the function signature because I was calling it from my EnemyBase. After hours of fail attempts at getting the code to compile, I thought to myself “Shoot, what if I just add the interface to the node, create a signature block that does nothing and see if that works?” Spoiler alert… it did!


<Reference Image of my BT Node Task header file>


<Reference Image of the function that was needed to be added in order for the interface to work>

I don’t know enough about interfaces to be able to explain why this worked. Not even sure if this the correct implementation, I just know that when I added the interface to the BT Task Node it worked! Once I had solved this issue, I was able to speed through the rest of the nodes that required a call to this function.

Coding is a weird medium. Sometimes it feels like dark magic. Its like, you read and study the spell, you say the incantation, wave your wand, but nothing seems to happen, until BAM! The spell suddenly and randomly   casts and you’re just wondering, how did I do that?

 

 

Support this post

Did you like this post? Tell us

Leave a comment

Log in with your itch.io account to leave a comment.