翻译自Udemy的视频课程introduction-to-unreal-engine-4-ability-system
AI SetUp设置简单的敌人AI
1、设置行为树
01、创建BehaviorTree行为树,命名为BT_Enemy,再创建一个BlackBoard,命名为BB_Enemy.其中行为树类似于CPU,提供计算的功能,BlackBoard相当于内存,提供数据存储的功能
02、打开行为树,指定BlackBoard,
并在黑板中创建一个Key(键值),为Object类型,指向Actor。用于保存一个指向玩家的引用
03、创建一个Task(任务), 命名为BT_UpdateTarget,在该任务中执行获取玩家位置的逻辑
04、在BT_UpDateTarget这个任务里,首先调用事件 Event Receive Excute AI(这是行为树执行该任务时的入口),获取All Actor of class (BP_BasePlayerController),由于只有一个BP_BasePlayerController,可以直接Get第一个,获取Controlled Pawn,这个就是玩家的角色,通过Set Blackboard Value as Object为BB_Enemy这个黑板中的Target赋值
05、创建一个蓝图AIController,命名为AIC_Enemy,这个AIController的作用就是运行行为树
然后需要指定敌人角色应用这个AIController
06、创建一个Task,命名为BT_Attack,用于执行MeleeAttack
06、完善BehaviorTree(查找玩家位置,移动到玩家位置,进行攻击,至少等待1.5s后再攻击)
07、需要添加NavMesh,使得MoveTo能够工作
选择Volume->NavMesh,拖放到场景中
2、设置TeamID和禁止玩家角色死亡后的输入动作
有多个敌人,他们不能够互相伤害。设置TeamID,在SwordCollision事件中,判断是否teamID不同,不同的话,那么就发送伤害处理事件给GA_Melee
uint8 GetTeamID()const;
UFUNCTION(BlueprintCallable)
bool IsOtherHostile(ABaseCharacter* Other);//用于判断TeamID是否不同
protected:
bool bIsDeath;uint8 TeamID;
//根据Controller的类型设置TeamID
void AutoDetermineTeamIDByControllerType();
//在Dead里禁用输入
void Dead();
当kill掉敌人后也要终止行为树的执行,自身角色死亡的时候终止输入的获取
#include "public/BaseCharacter.h"
#include "BaseAttributeSet.h"
#include "GameFramework/PlayerController.h"
#include "AIController.h"
#include "BrainComponent.h"
// Sets default values
ABaseCharacter::ABaseCharacter()
{
// 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;
AbilitySystemComp = CreateDefaultSubobject<UAbilitySystemComponent>("AbilitySystemComp");
AttributeSetComp = CreateDefaultSubobject<UBaseAttributeSet>("AttributeSetComp");
bIsDeath = false;
TeamID = 255;
}// Called when the game starts or when spawned
void ABaseCharacter::BeginPlay()
{
Super::BeginPlay();
//在BeginPlay中动态的绑定委托
AttributeSetComp->OnHealthChange.AddDynamic(this, &ABaseCharacter::OnHealthChange);
AutoDetermineTeamIDByControllerType();
}void ABaseCharacter::OnHealthChange(float Health, float MaxHealth)
{
if (Health <= 0.f&& !bIsDeath) {
//生命值小于0,调用蓝图事件来播放死亡动画
bIsDeath = true;
BP_Die();
Dead();
}
BP_OnHealthChange(Health, MaxHealth);//通知蓝图事件调用
}uint8 ABaseCharacter::GetTeamID()const
{
return TeamID;
}bool ABaseCharacter::IsOtherHostile(ABaseCharacter* Other)
{
return TeamID!=Other->GetTeamID();
}void ABaseCharacter::AutoDetermineTeamIDByControllerType()
{
if (GetController() && GetController()->IsPlayerController()) {
TeamID = 0;
}}
void ABaseCharacter::Dead()
{
APlayerController* PC = Cast<APlayerController>(GetController());
if (PC)
{
PC->DisableInput(PC);
}
AAIController* AIC = Cast<AAIController>(GetController());
if (AIC)
{
AIC->GetBrainComponent()->StopLogic("Dead");
}
}
为了能够成功编译,需要在工程的cs文件中添加“AIModule”
修改SwordCollision的Overlap事件
至今为止,玩家角色已经可以被敌人击杀
翻译这个系列是因为这个视频时当前为数不多的系统讲解GAS的视频。同时也是一份记录,用于自己日后的查阅和参考。下一节继续记录使用GAS实现生命回复的技能