在UE4编辑器中,打开内容浏览器,右击鼠标,创建传说中的行为树:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQTM2MzA2MjM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />

之后便会得到存在一个根节点的空的行为树:

右側是设置行为树的黑板资源,此资源可自己创建与定义。实质就是不同bot之间协调时使用的一些公共内存罢了。UE4仅仅是简单实现。就是一些映射罢了。当然不用也能够哦。亲!

设置一颗例如以下行为树,和官网shootergame一样:

之后为了让此行为树跑起来。我们须要把他与我们的bot关联。在我们定义的bot中

在编辑器中赋值:

虽说这个行为树定义在这里,可是我们常常会在其controller中调用(来自ShooterAIController类中的代码):

AShooterAIController::AShooterAIController(const class FPostConstructInitializeProperties& PCIP) : Super(PCIP)
{
BlackboardComp = PCIP.CreateDefaultSubobject<UBlackboardComponent>(this, TEXT("BlackBoardComp"));//创建黑板组件 BehaviorComp = PCIP.CreateDefaultSubobject<UBehaviorTreeComponent>(this, TEXT("BehaviorComp"));//创建行为树组件 bWantsPlayerState = true;
}
//此方法在控制类(controller)关联肉身(APawn。UE4为人物增添了角色类。当然也是APawn的子类)时调用。熟悉UDK脚本的应该知道。
void AShooterAIController::Possess(APawn* InPawn)
{
Super::Possess(InPawn); AShooterBot* Bot = Cast<AShooterBot>(InPawn); // start behavior
if (Bot && Bot->BotBehavior)//由于在编辑器中已经赋值,所以这里行为树指针的值非空
{
BlackboardComp->InitializeBlackboard(Bot->BotBehavior->BlackboardAsset);//利用黑板资源初始化黑板组件
//获取黑板中的键ID
EnemyKeyID = BlackboardComp->GetKeyID("Enemy");
NeedAmmoKeyID = BlackboardComp->GetKeyID("NeedAmmo");
//启动行为树
BehaviorComp->StartTree(Bot->BotBehavior);
}
}

能够看出这里便使得AIController与我们创建的黑板资源与行为树资源相关联。

最后我们看看,上面行为树中的服务是啥回事?先看UE4中:

这三个关键类UBTService_BlackboardBase,UBTServe_BlueprintBase,UBTService_DefaultFoces便是UE4为我们创建的主要的服务类,在shooterGame项目里,是继承的中间UBTServe_BlueprintBase类,显然是为了在蓝图中可视化。

注意当中的FindClosestEnemy函数,这是哪里来的??,请看AShooterAIController类中:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQTM2MzA2MjM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />

	UFUNCTION(BlueprintCallable, Category=Behavior)//不用说这样的声明是啥意思,看上图
void FindClosestEnemy();
void AShooterAIController::FindClosestEnemy()
{
APawn* MyBot = GetPawn();
if (MyBot == NULL)
{
return;
} const FVector MyLoc = MyBot->GetActorLocation();
float BestDistSq = MAX_FLT;
AShooterCharacter* BestPawn = NULL; for (FConstPawnIterator It = GetWorld()->GetPawnIterator(); It; ++It)
{
AShooterCharacter* TestPawn = Cast<AShooterCharacter>(*It);
if (TestPawn && TestPawn->IsAlive() && TestPawn->IsEnemyFor(this))
{
const float DistSq = (TestPawn->GetActorLocation() - MyLoc).SizeSquared();
if (DistSq < BestDistSq)
{
BestDistSq = DistSq;
BestPawn = TestPawn;
}
}
} if (BestPawn)
{
SetEnemy(BestPawn);
}
}

相似的有ShootEnemy:

	UFUNCTION(BlueprintCallable, Category=Behavior)
void ShootEnemy();
void AShooterAIController::ShootEnemy()
{
AShooterBot* MyBot = Cast<AShooterBot>(GetPawn());
AShooterWeapon* MyWeapon = MyBot ? MyBot->GetWeapon() : NULL;
if (MyWeapon == NULL)
{
return;
} bool bCanShoot = false;
AShooterCharacter* Enemy = GetEnemy();
if (Enemy && Enemy->IsAlive() && MyWeapon->GetCurrentAmmo() > 0)
{
if (LineOfSightTo(Enemy, MyBot->GetActorLocation()))
{
bCanShoot = true;
}
} if (bCanShoot)
{
MyBot->StartWeaponFire();
}
else
{
MyBot->StopWeaponFire();
}
}

UE4 中的人工智能解析—ShooterGame为例的更多相关文章

  1. Java并发编程中的设计模式解析(二)一个单例的七种写法

    Java单例模式是最常见的设计模式之一,广泛应用于各种框架.中间件和应用开发中.单例模式实现起来比较简单,基本是每个Java工程师都能信手拈来的,本文将结合多线程.类的加载等知识,系统地介绍一下单例模 ...

  2. UE4中使用数据表(Data Table)

    本文依据官方文档数据驱动游戏性元素整理而来. 做过游戏的应该都清楚,如果游戏稍微有点规模,那么使用数据驱动来做游戏一般是必不可少的一步,一般也就是策划通过本表的方式来解决.下面我们来简单说一下UE4中 ...

  3. .NET Core中的CSV解析库

    感谢 本篇首先特别感谢从此启程兄的<.NetCore外国一些高质量博客分享>, 发现很多国外的.NET Core技术博客资源, 我会不定期从中选择一些有意思的文章翻译总结一下. .NET ...

  4. 【转载】 [unreal4入门系列之七] UE4中的Actor类和Pawn类

    原文地址: http://www.52vr.com/article-558-1.html 现在我们开始进入UE4的代码开发工作.首先,UE4的类框架是非常庞大的,看起来有点让人措手不及.不过正因为UE ...

  5. maven中使用dom4j解析、生成XML的简易方法

    此片文章主要写一些关于如何在maven工程中使用dom4j来解析或生成XML的建议方法,实际可使用的写法不仅限于如下所写的样例代码.此处进攻快速入手和提供思路使用. 首先配置pom.xml中的依赖的包 ...

  6. UE4 中的 C++ 编程介绍

    https://docs.unrealengine.com/latest/CHN/Programming/Introduction/index.html UE4 中的 C++ 编程介绍 Unreal ...

  7. 「Python 编程」编码实现网络请求库中的 URL 解析器

    摘要:怎么写出更短的代码并不是这次要讨论的话题.今天我们来研究一下:运行代码的计算机是如何找到目标服务器的? 相信各位 Python 开发者都用过 Requests 库,有些朋友还用过 WebSock ...

  8. UE4命令行参数解析

    转自:https://blog.csdn.net/u012999985/article/details/53544389 一 .命令行参数简述命令行参数是一连串的关键字字符串,当运行可执行文件时可以通 ...

  9. 前进中的人工智能——聚焦Faculty Summit 2015人工智能主题研讨会

    Summit 2015人工智能主题研讨会" title="前进中的人工智能--聚焦Faculty Summit 2015人工智能主题研讨会"> 在近几年上映的科幻大 ...

随机推荐

  1. 调整mysql数据库最大连接数

    1.查看mariadb数据库最大连接数,默认为151 MariaDB [(none)]> show variables like 'max_connections'; +------------ ...

  2. SpringBoot中使用过滤器Filter

    场景:API的参数都是经过加密的,于是在过滤器中,将获取到的请求的参数先解密再去进行处理 一.实现Filter接口 public class TestFilter implements Filter ...

  3. WinServer-授权规则

    授权规则: 使用谓词可以限制网站只能使用某一种请求 来自为知笔记(Wiz)

  4. [Unit Testing] Configure the Angular CLI to use the Karma Mocha test reporter

    Every Angular CLI generated project comes already with Karmapreinstalled as well a couple of executa ...

  5. 解题报告 之 HDU5317 RGCDQ

    解题报告 之 HDU5317 RGCDQ Description Mr. Hdu is interested in Greatest Common Divisor (GCD). He wants to ...

  6. CCControlExtension/CCControlPotentiometer

    #ifndef __CCCONTROLPOTENTIOMETER_H__ #define __CCCONTROLPOTENTIOMETER_H__ #include "CCControl.h ...

  7. Angular4集成ng2-file-upload

      在Github上找到了一个支持Angular4好用的文件上传组件ng2-file-upload,这里简单介绍一下这个库的集成使用方案.  本文基于该组件的1.2.1版. 1. 安装 安装非常简单, ...

  8. Glide中的回调:targets

    Glide隐藏了一大推复杂的在后台的场景,Glide做了所有的网络请求和处理在后台线程中,准备好了切回到ui线程后更新ImageView. 假设ImageView不再是图像的最后一步.我们只要Bitm ...

  9. php创建图像具体步骤

    php 的图像处理在验证码是最常见的,下面说下使用php创建图像的具体步骤. 简要说明:PHP 并不仅限于创建 HTML 输出, 它也可以创建和处理包括 GIF, PNG(推荐), JPEG, WBM ...

  10. SQL中的union

    在SQL中,如果我们查询一个班级的考试成绩数据,再统计考试成绩的总和,我们使用以下两条语句: select StudentName,Grade from Student select '总成绩',SU ...