在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. HDU 4253 Two Famous Companies

    Two Famous Companies Time Limit: 15000ms Memory Limit: 32768KB This problem will be judged on HDU. O ...

  2. WCF与WEB API区别

  3. [Ubuntu]安装中文输入法

    安装了英文版的Ubuntu12.04之后.使用ctrt+space无法切换到中文,才反应过来. 于是查询了下怎么在Ubuntu下安装和配置中文输入法. 第一步安装语言包: 在左側的菜单条中点击 sys ...

  4. Nginx系列(四)--工作原理

    上篇文章介绍了Nginx框架的设计之管理进程以及多个工作进程的设计.master进程用来管理通过fork子进程与子进程通信.子进程通过处理进程信号接到master的通信去处理请求. Nginx工作原理 ...

  5. hdu1525 Euclid&#39;s Game , 基础博弈

    http://acm.hdu.edu.cn/showproblem.php?pid=1525 题意: 两人博弈,给出两个数a和b, 较大数减去较小数的随意倍数.结果不能小于0,将两个数随意一个数减到0 ...

  6. myeclipse配置内存

    1.javaee项目假设耗费的内存过大,须要配置内存大小: 下图是配置tomcat结果:Optional program arguments: -Xms512M -Xmx512M -XX:PermSi ...

  7. js算法:分治法-棋盘覆盖

    在一个 2^k * 2^k 个方格组成的棋盘中,若恰有一个方格与其他方格不同.则称该方格为一特殊方格,称该棋盘为一特殊棋盘.显然特殊方格在棋盘上出现的位置有 4^k 种情形.因而对不论什么 k> ...

  8. js调节图片的亮度

    js调节图片的亮度:(使用CSS3的滤镜) 1.实现点亮图标.熄灭图标的效果 效果图: 页面代码: <!DOCTYPE html> <%@ page language="j ...

  9. sql 跟踪

    目录 1 sql跟踪 1.1 alter session 1.2 DBMS_MONITOR 1.3 DBMS_SESSION 1.4 oradebug模式 1.5 触发器的模式启用sql 跟踪 1.6 ...

  10. proxy in java

    [Static] IFeature.java ImpicateF.java Runport.java StaticProxy.java IFeature.java package UProxy.sta ...