Download

Help Please VERY STUMPED? Key not setting, DebugMessage printing "0" to screen

Could really use some help/advice here. This Behavior Tree stuff isn’t really documented yet so having some trouble setting these keys properly. Also stumped as to why my DebugMessage is printing “0” in Blue color.

Behavior Tree
27a85c05c368441fa7a9d1bcb23ee95c078f45d4.jpeg

Blackboard Key
d5d9e69a7aed51d92635ee551b4a6ab88e302cb3.jpeg

in BTService_FindAndDetectPlayer.cpp



void UBTService_FindAndDetectPlayer::ReceiveTick(AActor * OwnerActor, float DeltaSeconds)
{
	AActor * PtrToAnActor = NULL;
	UBehaviorTreeComponent* MyComp = Super::CurrentCallOwner;
	if (MyComp == NULL)
	{
		return;
	}

	for (TObjectIterator<AActor> Itr; Itr; ++Itr)
	{
		//any coditions on choosing which actor, such as name or other things;

		if (Itr->GetName()=="PlayerDetTest")
		{
			//Assign your created Ptr to actual Actor in game world
			PtrToAnActor = *Itr;
			GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, "AM I WORKING?");  //WHY THE F IS THIS PRINTING "0"??
			MyComp->GetBlackboardComponent()->SetValueAsObject(PointKey.SelectedKeyID, PtrToAnActor); //PointKey is set in the BehaviorTree to Player...I have TargetPoint named "PlayerDetTest" in level.
			return;
		}

	}

	//no actor found, return
	if (!PtrToAnActor) return;
}


in .h



UCLASS()
class UBTService_FindAndDetectPlayer : public UBTService_BlueprintBase
{
	GENERATED_UCLASS_BODY()

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

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Blackboard)
	FBlackboardKeySelector PointKey;
};


All literal text strings should be wrapped with the macro “TEXT”. This is because all text / strings in Unreal Engine are unicode.



GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, TEXT("AM I WORKING?"));


However, if you want to be on the super safe side, you could also wrap the text in an FString since that is actually the parameter type the function is looking for.



GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, FString(TEXT("AM I WORKING?")));


Yeah I had it like this before. I forgot to change it back. With TEXT("") and “” it prints 0 either way. It works fine when I call this directly from an Actor. Is this the same as the “Print String” function in Blueprint?

Any input on the rest of the code and why it’s not setting Player key to anything?? I wonder if my Blackboard pointer is wrong…

Are you sure you are hitting the AddOnScreenDebugMessage? I suspect that blue zero may be coming from some other source since you are printing in yellow there. Make sure you set a breakpoint and that you actually hit the debug message.

If you aren’t getting inside that conditional, the problem may be with the “if (Itr->GetName()==“PlayerDetTest”)” I haven’t double-checked, but I’m not sure if that syntax works properly since you don’t have the string literal wrapped in the TEXT macro (TEXT(“PlayerDetTest”)).

If your conditional is firing, let me know and I’ll take another look at that specific function. (I don’t normally use that, and we’re trying to eliminate the use of global variables in the engine generally.) You might try calling the Blueprint PrintString function instead, which you can find in KismetSystemLibrary.h. You’d call it like this:



UKismetSystemLibrary::PrintString(PtrToAnActor, FString(TEXT("AM I WORKING?")), true, true);


WorldContextObject is any UObject from which a world can be retrieved. For example, any Actor would be fine, which is why I passed in the PtrToAnActor which you’d just set (and was not NULL). I can’t recall all of the other classes that are supported, but I suspect Components are supported because you can get an Actor (owner) from the component. Many other classes are also supported.

(You can specify the yellow color as an optional final parameter if you like.)

A few more comments:
Using TObjectIterator is potentially very costly in terms of performance, because you’ll iterate over every actor in the game! If it’s a large number of actors, that can really add up. It’s generally better to pick as specific a class as you can, depending on what the actor type you’re trying to find. For instance, if you were iterating over characters, use TObjectIterator.

Lastly, it looks like you accidentally left a line in your function from an earlier version, because this code isn’t doing anything:



//no actor found, return
if (!PtrToAnActor) return;


You return anyway right after that line. So I presume at some point you had other code there, but you can remove the line now.

I hope this helps!

My ReceiveTick function isn’t even running. The blue 0 was coming from somewhere else…still not sure as I have no other print calls anywhere. That issue has been resolved.

I have overloaded ReceiveTick in a class extended from ACharacter and that ReceiveTick function worked just fine.

One thing I have noticed, is that REGARDLESS of the content of BTService_FindAndDetectPlayer, it always tries to tick innately through the Behavior Tree… I have verified this by using both an empty BTService_Blueprint BP and removing all functions other than the constructor from my .cpp. It looks like Services tick by default at a rate set in the editor.

Am I correct in assuming that the ReceiveTick function is “ticked” automatically by the engine without needing to be called? (like BeginPlay())

  1. Don’t make 2 threads about the same thing :wink:
  2. Try adding PrimaryActorTick.bCanEverTick = true in the class constructor.

UPDATE: BTService_FindAndDetectPlayer is not even showing up in the editor. This is what is going on.

I created a blueprint for BTService named FindAndDetectPlayer and after deleting this, it still shows up under Services. It’s basically an empty Service that does nothing.

Unfortunately this leads to another problem.…Why isn’t code extended from BTService_BlueprintBase showing up as a Service inside the Behavior Tree?

First of all, please do not use *_BlueprintBase classes when creating native c++ implementations. Those, as name suggest, are wrappers for blueprint functionality and some functions may not be even called without being implemented through blueprint objects. For example, Receive events won’t be called if object don’t have their blueprint implementation - performance reasons.

Try creating your service using either UBTService or UBTService_BlackboardBase (built in support for single blackboard key), the same rules goes for task and decorators nodes. Tick function can be implemented using TickNode() override (will be called with requested interval, instead of every frame).

That actually makes too much sense :smiley:

It would appear that I went full potato here. The BTTasks I have created are working fine…and consequently, those are _BlackboardBase’s

Will try this out as soon as I can. Thanks.

Oops! Somehow I missed that inheritance point; I got bogged down in your cpp and didn’t pay enough attention to the header. Sorry about that.

So did I…it has been driving me up the wall. I didn’t realize that it was an old empty blueprint showing up in the editor until I made a project exclusively to test BTService…

It’s very simply ,first you should read couple of books about C++ ,start with The Pragmatic Programmer: From Journeyman to Master by Andrew Hunt and David Thomas than Effective C++ and More Effective C++ by Scott Meyers ,and other staff like that .Maybe than you can understand code more clearly also it will increase your basic “brain level” . And when you’ll be ready to code ,think whether it worth to do this or not…cuz maybe you just get nothing at the end ,so why you need all of these efforts.Who knows…