UE4 中的人工智能解析—ShooterGame为例
在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为例的更多相关文章
- Java并发编程中的设计模式解析(二)一个单例的七种写法
Java单例模式是最常见的设计模式之一,广泛应用于各种框架.中间件和应用开发中.单例模式实现起来比较简单,基本是每个Java工程师都能信手拈来的,本文将结合多线程.类的加载等知识,系统地介绍一下单例模 ...
- UE4中使用数据表(Data Table)
本文依据官方文档数据驱动游戏性元素整理而来. 做过游戏的应该都清楚,如果游戏稍微有点规模,那么使用数据驱动来做游戏一般是必不可少的一步,一般也就是策划通过本表的方式来解决.下面我们来简单说一下UE4中 ...
- .NET Core中的CSV解析库
感谢 本篇首先特别感谢从此启程兄的<.NetCore外国一些高质量博客分享>, 发现很多国外的.NET Core技术博客资源, 我会不定期从中选择一些有意思的文章翻译总结一下. .NET ...
- 【转载】 [unreal4入门系列之七] UE4中的Actor类和Pawn类
原文地址: http://www.52vr.com/article-558-1.html 现在我们开始进入UE4的代码开发工作.首先,UE4的类框架是非常庞大的,看起来有点让人措手不及.不过正因为UE ...
- maven中使用dom4j解析、生成XML的简易方法
此片文章主要写一些关于如何在maven工程中使用dom4j来解析或生成XML的建议方法,实际可使用的写法不仅限于如下所写的样例代码.此处进攻快速入手和提供思路使用. 首先配置pom.xml中的依赖的包 ...
- UE4 中的 C++ 编程介绍
https://docs.unrealengine.com/latest/CHN/Programming/Introduction/index.html UE4 中的 C++ 编程介绍 Unreal ...
- 「Python 编程」编码实现网络请求库中的 URL 解析器
摘要:怎么写出更短的代码并不是这次要讨论的话题.今天我们来研究一下:运行代码的计算机是如何找到目标服务器的? 相信各位 Python 开发者都用过 Requests 库,有些朋友还用过 WebSock ...
- UE4命令行参数解析
转自:https://blog.csdn.net/u012999985/article/details/53544389 一 .命令行参数简述命令行参数是一连串的关键字字符串,当运行可执行文件时可以通 ...
- 前进中的人工智能——聚焦Faculty Summit 2015人工智能主题研讨会
Summit 2015人工智能主题研讨会" title="前进中的人工智能--聚焦Faculty Summit 2015人工智能主题研讨会"> 在近几年上映的科幻大 ...
随机推荐
- GitHub上搭建私人hexo博客操作教程
GitHub上搭建hexo博客 安装GitGit:主要用于上传博客页面到github和命令操作安装NodeNode.js:Hexo的运行环境安装HexoHexo:博客程序打开安装Git后的生成的右键菜 ...
- poj 3259 bellman最短路推断有无负权回路
Wormholes Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 36717 Accepted: 13438 Descr ...
- 广播BroadcastReceiver(2)
有序广播的优先级: 发送有序广播的方法有: public void sendOrderedBroadcast(Intent intent,String receiverPermis ...
- @dynamic与@synthesize的差别
如今非常多时候我们都已经不再使用@synthesizekeyword了,可是须要了解当中的原理: 一.@dynamic与@synthesize的差别 @property有两个相应的词.一个是@synt ...
- node08---EJS模版
四.模板引擎 <a href="<%= url %>"><img src="<%= imageURL %>" alt= ...
- mysql安装,数据库连接
安装教程http://jingyan.baidu.com/article/e3c78d64412ae83c4c85f5fd.html 首先打开MySQL官网,找到Downloads标签,点击进入.如果 ...
- poj_3071概率dp
确定好对手就简单了. #include<iostream> #include<cstdio> #include<cstring> #include<algor ...
- Pocket英语语法---四、should的同义词是谁
Pocket英语语法---四.should的同义词是谁 一.总结 一句话总结:should表示劝告,建议,命令,其同义词是ought to,should强调主观看法,ought to强调客观要求.在疑 ...
- [雅礼NOIP2018集训 day4]
感觉状态极差啊,今天居然爆零了 主要是以下原因: 1.又是T1看错题肝了两个小时,发现题意理解错误瞬间心态爆炸 2.T2交错了文件名 3.T3暴力子任务和正解(假的)混在一起,输出了两个答案 都想为自 ...
- css实现左右两端对齐均匀排列 text-align: justify
1.实现一行文字的两端对齐均匀排列 为了实现效果只是加上一个text-align: justify;是没效果的.所以需要加上一个空标签<span><i>都可以,也可以用伪类来写 ...