AIEnemy.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "AIController.h"
#include "Enemy.h"
#include "AIEnemy.generated.h"
/**
*
*/
UCLASS()
class PACMAN_API AAIEnemy : public AAIController
{
GENERATED_BODY()
public:
// 要重写的函数
// 相当于beginplay,每当开启一个AI的时候调用,首先执行OnPossess
void OnPossess(class APawn* InPawn) override;
// 移动停止后调用
virtual void OnMoveCompleted(FAIRequestID RequestID, const FPathFollowingResult& Result) override;
void SearchNewPoint();
void GoHome();
void ReArm();
void StopMove();
private:
class AEnemy* Bot;
FVector HomeLocation;
FTimerHandle DeadTime;
};
AIEnemy.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Public/AIEnemy.h"
#include "NavigationSystem.h"
#include "Public/TimerManager.h"
void AAIEnemy::OnPossess(class APawn* InPawn)
{
Super::OnPossess(InPawn);
// 获得Enemy,肉体
Bot = Cast<AEnemy>(InPawn);
HomeLocation = Bot->GetActorLocation();
SearchNewPoint();
}
void AAIEnemy::OnMoveCompleted(FAIRequestID RequestID, const FPathFollowingResult & Result)
{
if (!Bot->bIsDead)
{
SearchNewPoint();
}
}
void AAIEnemy::SearchNewPoint()
{
// 判断导航网格在不在
UNavigationSystemV1* NavMesh = UNavigationSystemV1::GetCurrent(this);
// 如果在
if (NavMesh)
{
// 设置搜索半径
const float SearchRadius = 1000.0f;
// 设置一个点
FNavLocation RandomPt;
// 以敌人的位置为中心,这个半径为范围,找一个点,
const bool bFound = NavMesh->GetRandomReachablePointInRadius(Bot->GetActorLocation(), SearchRadius, RandomPt);
// 如果能找到
if (bFound)
{
// 移动到这个点
MoveToLocation(RandomPt);
}
}
}
void AAIEnemy::GoHome()
{
MoveToLocation(HomeLocation);
GetWorldTimerManager().SetTimer(DeadTime, this, &AAIEnemy::ReArm, 5.0f, false);
}
void AAIEnemy::ReArm()
{
GetWorldTimerManager().ClearTimer(DeadTime);
Bot->ReArm();
}
void AAIEnemy::StopMove()
{
StopMovement();
}
Enemy.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "Components/StaticMeshComponent.h"
#include "Enemy.generated.h"
UCLASS()
class PACMAN_API AEnemy : public ACharacter
{
public:
// 敌人是否死亡
bool bIsDead;
};
设置导航网格:
模式---体积---Nav Mesh Bounds Volume
拖到场景中,设置 Brush Settings
选择视口,按下 P 键,显示导肮网格的样子
上面的能拐弯,有绿色的线
需要设置导航网格
编辑---项目设置---引擎--导航网格物体
把Generation下的 Cell Size 改成 5
Cell Height 改成 2
这样导航网格不会穿墙
绿色就是可以通过的路径
这些绿色就是导航网格的范围
使用 GetWorldTimerManager(),需要引入头文件:#include "Public/TimerManager.h"