UEC++学习(十三)Ai服务AI Service / AI装饰 AI Decorator

目录

(1)优化逻辑

(2)使用AI Service 


        服务是可以添加到行为树节点的特殊类,具有自己的Tick功能,可以在里面写游戏逻辑,并且还能够更改黑板上的键

        这里主要是对UEC++学习(十一)和(十二)中的AI随机移动和追击玩家逻辑进行优化。如果不感兴趣的话可以直接跳转到第二步

创建BTService类,命名为STUFindEnemyService

(1)优化逻辑

在STUFindEnemyService.h中创建一个FBlackboardSelector变量,用于存储Ai感知组件寻找到的角色,重载TickNode函数

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AI")
		FBlackboardKeySelector EnemyActorKey;

	virtual void TickNode(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds) override;

在STUFindEnemyService.cpp中

GetBlackboardComponent():获得黑板组件

GetAIOwner():获得AiController

SetValueAsObject:将actor赋值给EnemyActorKey

#include "STUUtil.h"
#include "BehaviorTree/BlackboardComponent.h"
#include "AIController.h"
#include "Components/STUAIPerceptionComponent.h"


void USTUFindEnemyService::TickNode(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds)
{
	UBlackboardComponent* Blackboard = OwnerComp.GetBlackboardComponent();
	if (Blackboard)
	{
		AAIController* Controller = OwnerComp.GetAIOwner();
        //这是获得AI感知组件,是我自己写的模板类
		USTUAIPerceptionComponent* PerceptionComponent = STUUtil::GetSTUPlayerComponent<USTUAIPerceptionComponent>(Controller);
		if (PerceptionComponent)
		{
			//将蓝图key对应的值改为ai找到的角色
            //GetClosestEnemy():可以在C++学习(十二)中查看具体逻辑
			Blackboard->SetValueAsObject(EnemyActorKey.SelectedKeyName, PerceptionComponent->GetClosestEnemy());
		}
	}
	Super::TickNode(OwnerComp, NodeMemory, DeltaSeconds);
}

在AIController.h中,新建一个FName变量,用于获取上面逻辑用SetValueAsObject设置的Actor

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AI")
		FName FocusOnKeyName = "EnemyActor";

	AActor* GetFocusOnActor() const;

在AIController.cpp中

GetBlackboardComponent()->GetValueAsObject()

void ASTUAIController::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	AActor* AimActor = GetFocusOnActor();
	SetFocus(AimActor);

}

AActor* ASTUAIController::GetFocusOnActor() const
{
	if (GetBlackboardComponent())
	{
		//返回黑板中参数和FocusOnKeyName同名参数对应的值
		return  Cast<AActor>(GetBlackboardComponent()->GetValueAsObject(FocusOnKeyName));
	}
	return nullptr;
}

(2)使用AI Service 

在黑板蓝图中创建一个变量用于存储感知组件寻找到的角色,命名和AIController中的FocusOnKeyName对应值一样

在行为树蓝图中添加一个Selector选择器节点,从左往右执行,当左边不满足执行条件之后就会执行右边

在选择器中添加服务,因为FindEnemy这个逻辑是需要一直检测的,所以这一开始的选择器中添加。

将EnemyActorKey对应的值改为黑板中的变量

        创建两个序列,一个用于检测到角色之后攻击角色,一个用于AI丢失角色视野后随机移动,分别修改命名为Attack和随机移动。

        添加NextLocation和MoveTo两个任务,NextLocation任务的实现逻辑在C++学习(十一)中,修改NextLocation和MoveTO相关的参数

添加两个装饰器,选择黑板类型,目的是当Ai在执行随机移动逻辑时,检测到角色后,停止执行随机移动。有点类似于if语句。

分别修改两个装饰器的参数

最终效果:

按 “ 键查看AI调试信息,按下 4 可以查看感知组件信息

追击角色以及巡逻

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值