Behavior Tree Service in C++

Hey there,

i’m currently creating some VERY basic AI in C++. I only want to use the Behavior Tree, but create the rest in C++.
I got everything working except the service. In the service, i’m calling the “SearchEnemy()” function that searches and sets the next enemy. This works if i create the logic in Blueprints. If i do the same in the C++ version of the Service, the service shows up with “No Tick” in the Tree.

First one is C++, second one is BP:

http://puu.sh/gPNlM/956f9dfc49.png

Here is my C++ code for the service:

Header.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "BehaviorTree/Services/BTService_BlueprintBase.h"
#include "MyHeaders.h"
#include "MeeleFollowEnemyService.generated.h"

/**
 * 
 */
UCLASS(BlueprintType, Blueprintable)
class SMALLCOOPTD_API UMeeleFollowEnemyService : public UBTService_BlueprintBase
{
	GENERATED_BODY()

public:

	UMeeleFollowEnemyService(const FObjectInitializer& ObjectInitializer);

	virtual void ReceiveTick(AActor* OwnerActor, float DeltaSeconds) override;
	
};

CPP:

// Fill out your copyright notice in the Description page of Project Settings.

#include "SmallCoopTD.h"
#include "MeeleFollowEnemyService.h"


UMeeleFollowEnemyService::UMeeleFollowEnemyService(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	
}

void UMeeleFollowEnemyService::ReceiveTick(AActor* OwnerActor, float DeltaSeconds)
{
	ABaseAIController* BotController = Cast<ABaseAIController>(OwnerActor);

	if (BotController)
	{
		BotController->SearchEnemy();
	}
}

Same thing in BP:

So what exactly am i missing here? Do i need to create services in BP? I don’t think so x)

I can’t find any information on how to setup a service in C++. Do i miss something to let that service tick?

This what i found from source code ReceiveTick will be call here

else if (ReceiveTickImplementations & FBTNodeBPImplementationHelper::Generic)
{
	ReceiveTick(ActorOwner, DeltaSeconds);
}

and the ReceiveTickImplementations only valid if it have the blueprint function name ReceiveTick in blueprint.

ReceiveTickImplementations = FBTNodeBPImplementationHelper::CheckEventImplementationVersion(TEXT("ReceiveTick"), TEXT("ReceiveTickAI"), this, StopAtClass);

and

int32 CheckEventImplementationVersion(FName GenericEventName, FName AIEventName, const UObject* Ob, const UClass* StopAtClass)
	{
		const bool bGeneric = BlueprintNodeHelpers::HasBlueprintFunction(GenericEventName, Ob, StopAtClass);
		const bool bAI = BlueprintNodeHelpers::HasBlueprintFunction(AIEventName, Ob, StopAtClass);
		
		return (bGeneric ? Generic : NoImplementation) | (bAI ? AISpecific : NoImplementation);
	}

Seem like ReceiveTick must be a blueprintfunction to able to execute. Maybe u can try put UFUNCTION() on the ReceiveTick, and it will consider that as BlueprintFuction ?

Hm ok,

i will have a look at it. The API says it is a BlueprintImplementableEvent. This means i CAN be overriden through a Blueprint version. But i still don’t understand why this Service can’t be created in C++.

I can even choose the C++ file (no BP child) in the Service list. But like i showed, i gives the no tick error.

Let’s see if adding UFUNCTION or just create a child BP class will fix something.

Thanks so far (:

Ok, i forgot, an override function can’t have a UFUNCTION() makro. It will just use the original superclass properties. :confused:

Ok, thanks Duncan Dam.

It just created a BP of my custom Service and added a blanc Event Receive Tick that does nothing. Now the Service works and calls the C++ version.

I don’t understand why this is necessary, but i guess that has some inner logic.

Maybe our AI Lord @MieszkoZ can add some information on this.

Thanks for your help Duncan. For now it is working (:

yeah, weird, i think that’s some kind of optimize for the AI, they should have some variable to toggle this.

Yop, that would be a good idea. Now i’m questioning around why my AI isn’t moving around a cube, although “MoveTo” should use the NavMesh.

But that’s another problem -

This is all by design. To create a C++ implementation of a service you need to derive from UBTService not UBTService_BlueprintBase :slight_smile: Let me know if you encounter any issues while doing so.

Cheers,

–mieszko

Hey, thanks MieszkoZ (: I didn’t pick the UBTService, because when i looked into the API for it, i missed some function that i thought i would need.

For now i created everything in BP. I will try it with the UBTService when i come to convert this into C++. Thanks for your answer so far. I will report back when i encounter issues!