导航的物体要有移动组件
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/AI/STrackerBot.h"
#include "Components/StaticMeshComponent.h"
#include "NavigationSystem.h"
#include "Kismet/GameplayStatics.h"
#include "GameFramework/Character.h"
#include "NavigationPath.h"
//要在 build.cs 中添加 "NavigationSystem"
// Sets default values
ASTrackerBot::ASTrackerBot()
{
// 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;
MeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MeshComp"));
RootComponent =(USceneComponent*)MeshComp;
MeshComp->SetCanEverAffectNavigation(false);
MeshComp->SetSimulatePhysics(true);
}
// Called when the game starts or when spawned
void ASTrackerBot::BeginPlay()
{
Super::BeginPlay();
GetNextPathPoint();
}
FVector ASTrackerBot::GetNextPathPoint()
{
//找到主角
ACharacter* PlayerPawn= UGameplayStatics::GetPlayerCharacter(this, 0);
const FVector StartLocation = GetActorLocation();
//获取路径
//第一个参数 当前的世界
//第二个参数 起始点
//第三个参数 目的地
UNavigationPath* NavPath= UNavigationSystemV1::FindPathToActorSynchronously(this, StartLocation,PlayerPawn);
if (NavPath->PathPoints.Num()>1)
{
//PathPoints[0]是当前的位置
return NavPath->PathPoints[1];
}
return GetActorLocation();
}
// Called every frame
void ASTrackerBot::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
//获取向量的大小
float DistanceToTarget =( GetActorLocation()-NextPathPoint).Size();
if (DistanceToTarget<=RequireDistanceToTarget)
{
NextPathPoint=GetNextPathPoint();
}
else
{
FVector ForceDirection=NextPathPoint - GetActorLocation();
ForceDirection.Normalize(); //单位化
ForceDirection *= MovementForce;
//施加力
//物理模拟要设置true
//第三个参数代表是否受到质量的影响
MeshComp->AddForce(ForceDirection,NAME_None,true);
}
}
// Called to bind functionality to input
void ASTrackerBot::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
}