EQS优化,让AI知道什么地方不能走
首先进行小修改,创建一个新的AIEQS
新建一个测试pawn
把测试pawn放入场景内,在eqs中放入我们写的eqs任务,使用模拟游戏,就可以直接可视化eqs的选择坐标点
https://docs.unrealengine.com/5.0/en-US/environment-query-testing-pawn-in-unreal-engine/
这样调整eqs的时候可以更直观
添加距离检测,防止ai过于靠近pawn
修改为最小距离,最小距离为1000,并且调整Point Per Ring
如何防止AI导航到方块内
使用NavModifierVolume
在EQS内修改AI范围
也可以使用查询路径来判断AI在哪些方面不能进行行走,但是非常吃资源
自定义游戏模式
创建GameClass类
这里我也不放截图,直接复制代码
gamebase .h
// Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "AI/SAICharacter.h" #include "EnvironmentQuery/EnvQueryTypes.h" #include "GameFramework/GameModeBase.h" #include "SGameModeBase.generated.h" class UEnvQueryInstanceBlueprintWrapper; class UEnvQuery; /** * */ UCLASS() class ACTIONROUGELIKE_API ASGameModeBase : public AGameModeBase { GENERATED_BODY() protected: UPROPERTY(EditAnywhere,Category="AI") TSubclassOf
.cpp
// Fill out your copyright notice in the Description page of Project Settings. #include "SGameModeBase.h" #include "EnvironmentQuery/EnvQueryManager.h" #include "EnvironmentQuery/EnvQueryTypes.h" #include "EnvironmentQuery/EnvQueryInstanceBlueprintWrapper.h" #include "AI/SAICharacter.h" #include "SAttributeComponent.h" #include "EngineUtils.h" ASGameModeBase::ASGameModeBase() { SpawnTimerInterval =2.0f; } void ASGameModeBase::StartPlay() { //继承Base的StartPlay Super::StartPlay(); /*我们正在从我们的时间管理器对象创建一个计时器。 然后我们注册这个回调以使用我们的定时器句柄。 然后我们分配一个回调方法,在倒计时结束时触发。 最后我们设置倒计时时间为SpawnTimerInterval秒。*/ GetWorldTimerManager().SetTimer(TimerHandle_SpawnBots,this,&ASGameModeBase::SpawnTimerElapsed,SpawnTimerInterval,true); } void ASGameModeBase::SpawnTimerElapsed() { //执行EQS查询,在全局搜索内查询RunEQSQuery可以找到EnvQueryManage.cpp这个文件,在这个文件内可以找到这个函数 UEnvQueryInstanceBlueprintWrapper* QueryInstance = UEnvQueryManager::RunEQSQuery(this,SpawnBotQuery,this,EEnvQueryRunMode::RandomBest5Pct,nullptr); if(ensure(QueryInstance)) { //查询出一个节点后在5%这个误差内执行OnQueryCompleted这个函数 QueryInstance->GetOnQueryFinishedEvent().AddDynamic(this,&ASGameModeBase::OnQueryCompleted); } } //在玩家周围生成Bot void ASGameModeBase::OnQueryCompleted(UEnvQueryInstanceBlueprintWrapper* QueryInstance,EEnvQueryStatus::Type QueryStatus) { //确认是否生成 if(QueryStatus != EEnvQueryStatus::Success) { UE_LOG(LogTemp,Warning,TEXT("无法生成EQS:SpawnBotQuery!")) return; } //默认机器人为0 int32 NrOfAliveBots = 0; //判断机器人是否需要添加 for (TActorIterator
让AI在世界生成的时候自动添加AI控制器并执行
ASAICharacter::ASAICharacter() { // Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; PawnSensingComp = CreateDefaultSubobject
##报错,无法间接强制转换
查找资料后发现要手动引用
#include "EngineUtils.h"
这样就可以正确编译了
难度提升,随着时间增多的AI
创建一条曲线
添加曲线
最后把曲线放在Gamemode内
效果图