0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

UE4 EQSをC++から直接実行する

Posted at

概要

UnrealEngine4 の Environment Query System(EQS)をC++から直接実行するためのメモです。
Behavior Tree は使用しません。

参考

以下の記事を参考にいたしました、ありがとうございます。

公式:Environment Query System ユーザー ガイド
UE4 Document@com04 EQS
AIで色々悩んでみた:EQS編

環境

Windows10
Visual Studio 2017
UnrealEngine 4.26.2

関連ソース

Engine\Source\Runtime\AIModule\Classes\EnvironmentQuery\EnvQueryManager.h
Engine\Source\Runtime\AIModule\Classes\EnvironmentQuery\EnvQueryTypes.h
Engine\Source\Runtime\AIModule\Classes\EnvironmentQuery\EnvQuery.h

準備

現時点で公式マニュアルでは「実験的」となっていますが、エンジンプラグインとしてデフォルトで使用できるようです。

環境クエリを作る

コンテンツブラウザから右クリック -> AI -> 環境クエリ で作成します。

ジェネレータとテストを適当に。
envquery00.png

TestingPawn 経由でエディタで見るとこんな感じです。
envquery01.png

モジュールの設定

C++で扱うためにモジュールの追加設定をします。
GameplayTasksAIModuleの追加が必要です。

[Project].Build.cs
	PublicDependencyModuleNames.AddRange(
		new string[] {
			(省略)
			"GameplayTasks",	// ←追加
			"AIModule",			// ←追加
	});

関連クラス/データ型

UEnvQuery

環境クエリのデータ型。UDataAsset から継承されています。

FEnvQueryRequest

環境クエリを実行するためのラッパー。
これを経由して実行をします。ジェネレータへ渡すパラメータもこれを経由します。

FEnvQueryResult

結果を受け取るためのデータ型。ジェネレートしたアクター(アイテム)の情報がソートされて保持される模様。

C++からのEQS呼び出し

アクターコード

該当アクターに環境クエリデータを持たせます。アクターに参照を保持してUEエディターで設定をします。
次に実行用メソッドと結果受け取り用のデリゲートオブジェクトを用意します。

MyCharacter.h
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "EnvironmentQuery/EnvQueryTypes.h"
#include "EnvironmentQuery/EnvQuery.h"

class UEnvQuery;

UCLASS(config=Game)
class AMyCharacter : public ACharacter
{
	GENERATED_BODY()

	// ...省略...

public:
	// 環境クエリ
	UPROPERTY(EditAnywhere, Category = "AI", meta = (ToolTip="環境クエリ"))
		UEnvQuery*	MyEnvQuery = nullptr;

	// クエリ実行
	UFUNCTION(BlueprintCallable, meta = (ToolTip="クエリ実行メソッド"))
	void ExecuteMyEnvQuery();

	// 結果受け取り
	void MyEnvQueryResult(TSharedPtr<FEnvQueryResult> _Result);

};
cpp:MyCharacter.cpp
#include "MyCharacter.h"
#include "EnvironmentQuery/EnvQueryManager.h"


// クエリ実行
void AMyCharacter::ExecuteMyEnvQuery()
{
	FEnvQueryRequest _MyQueryRequest = FEnvQueryRequest(MyEnvQuery, this);

	// パラメータセット(ジェネレーターの該当パラメータをQueryParamsでバインド)
	_MyQueryRequest.SetFloatParam(FName(TEXT("SimpleGrid.GridSize")), 500.0f);
	_MyQueryRequest.SetFloatParam(FName(TEXT("SimpleGrid.SpaceBetween")), 200.0f);

	_MyQueryRequest.Execute(EEnvQueryRunMode::SingleResult, this, &AMyCharacter::MyEnvQueryResult);
}

// 結果受け取り
void AMyCharacter::MyEnvQueryResult(TSharedPtr<FEnvQueryResult> _Result)
{
	if (_Result->IsSuccsessful()) {
		// リザルトの中身を表示
		const int32	_ItemNum = _Result->Items.Num();
		for(int32 _Lp=0;_Lp<_ItemNum;_Lp++){
			FVector _Loc = _Result->GetItemAsLocation(_Lp);
			float	_Score = _Result->GetItemScore(_Lp);
			
			UE_LOG(LogTemp, Log, TEXT("%d, %.2f, (%.2f, %.2f)"), _Lp, _Score, _Loc.X, _Loc.Y );
		}
	}
}

クエリ実行時のパラメータは BehaviorTree で使用可能なものと同様に SingleResult RandomBest5Pct RandomBest25Pct AllMatching とありますが、それとは関係なく、FEnvQueryResultで受け取った結果はスコア順でソートされているようです。

UEエディタ設定

アクターのパラメータに作成した環境クエリを設定し、実行用メソッド ExecuteMyEnvQuery の呼び出しコードを用意します。(適当にキーボードから呼び出し)

example00.png

実行結果

FEnvQueryResult で受け取ったデータが表示されます。
実行時に EEnvQueryRunMode::SingleResult で結果を1つで指定していますが、中身はソートされてすべて持っているようです。

アウトプットログ
LogTemp: 0, 1.00, (-751.00, -299.00)
LogTemp: 1, 1.00, (-751.00, 101.00)
LogTemp: 2, 1.00, (-551.00, -499.00)
LogTemp: 3, 1.00, (-551.00, 301.00)
LogTemp: 4, 1.00, (-151.00, -499.00)
...省略
LogTemp: 32, 0.00, (249.00, -99.00)
LogTemp: 33, 0.00, (249.00, 101.00)
LogTemp: 34, 0.00, (249.00, 301.00)
LogTemp: 35, 0.00, (249.00, 501.00)

パラメータの受け渡し

クエリ実行時に以下のようにパラメータを渡しています。

パラメータの設定
_MyQueryRequest.SetFloatParam(FName(TEXT("SimpleGrid.GridSize")), 500.0f);
_MyQueryRequest.SetFloatParam(FName(TEXT("SimpleGrid.SpaceBetween")), 200.0f);

受け取るためには実行するEQSのジェネレータの DataBindingQueryParamsに変更し、パラメータ名を正しく設定する必要があります。
example01.png

まとめ

公式ページの「ネイティブ コードで EQS を使用する」を元に試してみた結果です。
EQSはAIとセットになっていますが、実際はAIに限らずに使うことができるため利用範囲が広がるのではないかと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?