How to implement BTService in C++

Hi there!
I am trying to convert my Behavior Tree tasks,services,etc. from BP into C++ for faster runtime and more customisation.

However I can’t seem to figure out how to implement a Service in C++.
As the events defined in BP like Event Receive Activation AI and Event Receive Tick(I use these currently,use Receive Activation to initialize some values) are not available in BTService.h but only in the blueprint version BTService_BlueprintBase.h
My class derives from BTService.
So i am not sure what functions correspond to those two functions in case of C++.
It’s especially confusing since the Service has already a Tick function just after creating the class.

Looked into the source code trying to figure out and found TickNode() and OnBecomeRelevant().However can’t really decide if these are what i need to replicate the blueprint execution.
Also if Tick function is already implemented how can i access it so i can implement what i want based on my BP?
Do i even need TickNode() if the Service has already a Tick() function when i look at it in the BT?

Sorry if this is obvious but my c++ skills or rather my source code reading ability is apparently lacking.

Thanks.

1 Like

Hi!

Errmm i got into service,tasks ands stuff by analyzing the services given by UE4.
For example UBTService_RunEQS shows how to tick, how to init and so on.

On BecomeRelevant/onCeaserelevant is mostly like what u want, since they get called whenever the service gets activated/deactivated(this means when the BHT is active on the node or a child).
I use becomerelevane/Cease for example to set blackboardkey observers, so ican react on changeing ot a value.

Hope it helps

In .h file:

virtual void OnBecomeRelevant(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;

In .cpp file (example):

// Constructor:
UBTService_MyService::UBTService_MyService(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	NodeName = "My Service";

	bNotifyBecomeRelevant = true;	// necessarily!!!
	//bNotifyCeaseRelevant = true;

	// accept only actors and vectors
	BlackboardKey.AddVectorFilter(this, GET_MEMBER_NAME_CHECKED(UBTService_MyService, BlackboardKey));

	BlackboardKey.SelectedKeyName = FName("NameOfKey");
	BlackboardKey.SelectedKeyType = UBlackboardKeyType_Vector::StaticClass();

	Interval = 0.5f;	// Any value.
	RandomDeviation = 0.f;
}

void UBTService_MyService::OnBecomeRelevant(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
	Super::OnBecomeRelevant(OwnerComp, NodeMemory);

	UBlackboardComponent* CurretnBlackboard = OwnerComp.GetBlackboardComponent();

	if (OwnerComp.GetAIOwner() && OwnerComp.GetAIOwner()->GetPawn())
	{
		AIPawn = OwnerComp.GetAIOwner()->GetPawn();
		...
	}
}

Add

bNotifyBecomeRelevant = true;

in constructor.