UE4 技能系统(GAS插件的使用) 03--AI SetUp设置简单的敌人AI

本文介绍了如何在Unreal Engine 4中为敌人设置简单的AI,包括创建行为树、BlackBoard,实现寻找玩家、移动及攻击等基本行为,并通过TeamID实现友军间不互相伤害。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

翻译自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实现生命回复的技能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值