19uec++ マルチプレイヤーゲーム [基本的な AI ナビゲーション]

最初にこの号のリソースをインポートします

ポーン クラスを継承する球体クラスを作成する

 それに静的コンポーネントを追加します

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
	class UStaticMeshComponent * MeshComponent;

==================================================================
#include "Components/StaticMeshComponent.h"

MeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MeshComponent"));
RootComponent = MeshComponent;

コンパイルし、ブループリント クラスを作成します。

そのコンポーネントを球に設定します

 

シーンにドラッグして、大きすぎることを確認します

 

そのための小さなボール メッシュ モデルを作成します。

最初にフォルダを作成します

 

 この小さなボール メッシュをフォルダにコピーしましょう

メッシュの名前を変更

 

このメッシュに入り、スケールを変更します

 

 このメッシュをクラスで置き換えます

shift+end で地面に近づける

 

次に、素材ファイルを作成します

 

最初にマテリアルを白に設定します

 メッシュへのマテリアルの割り当て

ナビゲーション本体をシーンにドラッグします

 次に、地面全体を覆うようにボリュームを拡大します

そして床下に埋め込む

 

 pを押すとナビゲーション範囲が表示されます

球自体もナビゲーションに影響を与えることがわかります

 

小さなボール メッシュ コンポーネントで、このチェックマークを削除します

 

 

この小さなボールの設計図を書きます

 次に、ボールにモバイル コンポーネントを追加します。

コンパイル、テスト、最初は本当にボールが動く 

 次に、移動ロジックをもう少し複雑にします

動きの速度を落とすと、ボールが私たちのお尻の後ろを追いかけていることがわかりました

 

====================================

ロジックを改善し続け、自動的にパスを追加できるようにします

最初にイベントをカスタマイズします

 

 テスト、パス ポイントが描画されました

 これを c++ ファイルに追加します。

小さなボールのヘッダー ファイルに、3 つの変数を追加します。

	//移动速度
	UPROPERTY(EditDefaultsOnly, Category = "TracerBot")
	float MovementForce;

	//是否让移动速度改变
	UPROPERTY(EditDefaultsOnly, Category = "TracerBot")
	bool bUseVelocityChange;

	//移动到目标的阈值
	UPROPERTY(EditDefaultsOnly, Category = "TracerBot")
	float RequiredDistanceToTarget;

 コンストラクターでこれら 3 つの変数を初期化し、メッシュ コンポーネントのシミュレートされた物理を有効にします。

AASTrackerBot::AASTrackerBot()
{
 	// Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
	MeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MeshComponent"));
	MeshComponent->SetSimulatePhysics(true);
	RootComponent = MeshComponent;

	MovementForce = 1000;
	bUseVelocityChange = false;
	RequiredDistanceToTarget = 100;
}

 ボールのヘッダファイルにパスポイントを求める機能とパスポイントの変数を追加

FVector GetNextPathPoint();

	//路径点
	FVector NextPathPoint;
#include "Components/StaticMeshComponent.h"
#include "GameFramework/Character.h"
#include"Kismet/GamePlayStatics.h"
#include "NavigationSystem.h"
#include "NavigationPath.h"
#include "DrawDebugHelpers.h"

 この関数を定義する

FVector AASTrackerBot::GetNextPathPoint()
{
	//得到0号玩家
	ACharacter *playerPawn = UGameplayStatics::GetPlayerCharacter(this, 0);
	//找到通往玩家的路径
	UNavigationPath *NavPath = UNavigationSystemV1::FindPathToActorSynchronously(this, GetActorLocation(), playerPawn);
	if (NavPath->PathPoints.Num() > 1)
	{
		//返回第二个点
		return NavPath->PathPoints[1];
	}
	else
	{
		return GetActorLocation();
	}
}

 ゲーム開始関数で、この関数を呼び出します

void AASTrackerBot::BeginPlay()
{
	Super::BeginPlay();
	NextPathPoint = GetNextPathPoint();
}

 各フレーム機能で動き続ける

void AASTrackerBot::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	//得到小球自身与下一个点的距离
	float DistanceToTarget = (NextPathPoint - GetActorLocation()).Size();
	//如果大于阈值,就继续滚
	if (DistanceToTarget > RequiredDistanceToTarget)
	{
		//小球的移动方向
		FVector ForceDirection = NextPathPoint - GetActorLocation();
		ForceDirection.Normalize();
		//小球的推力
		ForceDirection *= MovementForce;
		MeshComponent->ComponentVelocity.Size();
		MeshComponent->AddImpulse(ForceDirection, NAME_None, bUseVelocityChange);
		DrawDebugDirectionalArrow(GetWorld(), GetActorLocation(), GetActorLocation() + ForceDirection, 32, FColor::Red, false, 0.0f, 0, 1.0f);
	}
	//如果到达了路径点,就生成下一个点,继续移动
	else
	{
		NextPathPoint = GetNextPathPoint();
		DrawDebugString(GetWorld(), GetActorLocation(), "Target Reached!");
	}
	//在下一个目标点画一个球
	DrawDebugSphere(GetWorld(), NextPathPoint, 20, 12, FColor::Yellow, false, 0.0f, 0, 1.0f);

}

コンパイルしてから、ボールのメッシュ コンポーネントで、シミュレーションの物理特性をチェックします。

テストの成功

 

 

おすすめ

転載: blog.csdn.net/zhang2362167998/article/details/128076283