How to make a UEnvQueryContext that allows you to pull data from the Blackboard?

So AI store their “world knowledge” on their blackboards, but there doesn’t seem to be an ideal way to create a UEnvQueryContext that allows you to specify the key into the blackboard to get that data?

Example: I want to score points that are close to an actor in the blackboard.

Now I could pull that data out of the blackboard, put it on something else. Then have a context pull that. But that’s not a really great way to do it.

I could make a UEnvQueryContext_Blackboard class with a default FName Key and create derived classes changing the key, but that is pretty gross as well.

I’m really surprised this is a default feature. I would think this would be the next common thing you’d want other than the querier. Do you guys have a recommendation?

Hey Troy,

The main problem in using Blackboards with EQS is that EQS editor knows nothing about BB asset you’re going yo use your query with. Creating a UEnvQueryContext_Blackboard class utilizing FBlackboardKeySelector functionality should be pretty straightforward, but using it would result in given EQS query being tied to a given BB asset. If you use only one BB kind in your project it’s not sucha a big deal, but I can imagine most projects using more (I know every one of our current projects does).

Having said that it’s not such a bad idea :slight_smile: I think I’ll have a stab at it over the weekend. One warning though, it will spit errors right and left when used with wrong BB asset :smiley: I’ll update this thread once I get anywhere with it.

Cheers,

–mieszko

Yeah, we’d be fine binding an EQS to a blackboard. The amount of reuse an EQS between character types would be minimal, in our experience. There always ends up something we want to customize :slight_smile:

I’m really interested in what you come up with. Let us know if you have something or come up with a good idea on how to implement it. The context being a class type seems to be an issue for us.

We are still green at extending the EQS, so any tips would be helpful :slight_smile: Congrats on the nuclai talk btw. Sound very interesting!

Sorry for the delay, but I have all the details now.

Since “contexts” in engine-supplied tests and generators are just classes rather than class instances there’s no way to currently get direct blackboards support.

However, here’s what can be done. Classes in UE4 can be marked so that when required they’ll be created and edited “in line”, just add a EditInlineNew keyword to UCLASS definition (adding collapseCategories won’t hurt neither). To take advantage of this functionality one needs to add an UPROPERTY of that class, marked as Instanced.

So, in our case UEnvQueryContext needs to be marked as EditInlineNew and tests or generators that would want to take advantage of that need to declare their context as

UPROPERTY(EditDefaultsOnly, Instanced, Category = "YourDreamCategoryName")
UEnvQueryContext* AnyContext;

Then we could declare a Blackboard-based context, something like following:

UCLASS()
class AIMODULE_API UEnvQueryContext_Blackboard : public UEnvQueryContext
{
	GENERATED_BODY()

protected:
	UPROPERTY(EditAnywhere, meta = (EditCondition = "bBlackboardAssetSet"), Category = "EQS")
	FBlackboardKeySelector BlackboardKey;

	UPROPERTY(EditAnywhere, Category = "EQS")
	UBlackboardData* Blackboard;

	UPROPERTY(EditAnywhere, meta=(EditCondition="!bBlackboardAssetSet"), Category = "EQS")
	FName KeyName;

	UPROPERTY()
	bool bBlackboardAssetSet;

public:
	UEnvQueryContext_Blackboard(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
	virtual void ProvideContext(FEnvQueryInstance& QueryInstance, FEnvQueryContextData& ContextData) const override;
};

This is of course very limiting, because you can only use it for your own tests/generators, or you’d need to modify engine sources to update all the supplied tests. But if you really need this kind of functionality that’s how you can get it. On the bright side I think it’s a great idea so we’ll switch over to using class instances for contexts in the future, but I can’t promise any ETA.

Hope it helps.

1 Like

Oh, awesome. I’m going to try this. I went ahead and basically did this but I totally forgot about editinlinenew! I was just making these classes by hand as a stop gap for now. But I think this might work nicely. Going to try to get this done today. Thanks!

Let me know if you run into issues. Cheers!