UE4的AI c++代码初始化
2015-10-10 00:19
375 查看
AI的行动主要逻辑位于BehaviorTree内,AI的主要行动实现主要位于AIController中,而AI的记忆主要位于Blackboard内。下面是一些基本概念:
1.BehaviorTree内部含有一个成员是Blackboard。所以我们一般只给一个AICharacter内部设置一个成员BehaviorTree就行了,而在Editor内把Blackboard指认给BehaviorTree。
2.Editor内的Blackboard实际上是一个UBlackboardData,而不是一个Component,BehaviorTree内部的Blackboard成员是UBlackboardData。Component用于AIController内,在AIController我们会声明一个UBlackboardComponent,而在Editor里边创建的是一个UBlackboardData,是不一样的数据结构,UBlackboardComponent的初始化函数InitializeBlackboard接受一个参数是UBlackboardData。
3.UBlackboardData是初始化UBlackboardComponent的参数数据,而我们之后的操作主要在UBlackboardComponent上完成。比如UBlackboardComponent的函数SetValueAsVector就是给Blackboard上的一个Vector参数赋值。
4.BehaviorTree和Blackboard比较类似,也是有一个UBehaviorTree类型和一个UBehaviorTreeComponent类型,主要操作位于UBehaviorTreeComponent上,UBehaviorTree内只是数据。比如UBehaviorTreeComponent的一个函数是StartTree,而参数是UBehaviorTree。
5.可见Component一般实现逻辑,而需要用到的数据都是另一种类型。我们一般把数据部分,就是UBehaviorTree和UBlackboardData放在Character中,而把对应的两个Component放在AIController中,每次使用AIController调用自己Pawn内部的UBlackboardData和UBehaviorTree。这样就可以把操作和数据分离,达到Controller的复用。
6.需要使用UBehaviorTreeComponent或者UBlackboardComponent的地方需要添加必要的头文件。
这比较奇怪,因为直接声明Component是可以识别的,但是声明是不完整的,大概是因为默认include里边只有class声明没有实现吧。因为class有声明只是没实现,所以这些include可以加到cpp里,不用加到h里。遇到类型不完整都可以试试加入相应头文件来解决。
还要注意一点,要更改控制build的c#文件里代码,加一个AIModule进去,这样UE在build的时候才会把AI相关模块build进去。加了这一个模块之后,build时间也显著增加了。
下面介绍一下AI逻辑和记忆的编程方法:
1.在Editor内创建AIController,AICharacter,BehaviorTree,Blackboard文件,并把Blackboard指认给BehaviorTree内部的存储字段,把AIController指认给AICharacter作为操纵者。
2.首先在AICharacter内声明一个UBehaviorTree字段,注意UBlackboardData是包含在内部的。然后在Editor里边给他指认一个BehaviorTree。
3.在AIController内部声明两个UBlackboardComponent和UBehaviorTreeComponent字段。
4.初始化两个Component字段,首先使用CreateDefaultSubobject初始化内存,之后使用
5.之后如果AI的记忆要更变,就对UBlackboardComponent进行操作,它会对自己连接的Blackboard进行更改
6.AI的初始化和记忆更新写好之后,就是写AI逻辑的时候了,这关系到Editor里的BehaviorTree文件。BehaviorTree文件的编程方法和Blueprint类似,都是node连pin的。
具体关于BehaviorTree怎么用详见另一个文档。
1.BehaviorTree内部含有一个成员是Blackboard。所以我们一般只给一个AICharacter内部设置一个成员BehaviorTree就行了,而在Editor内把Blackboard指认给BehaviorTree。
2.Editor内的Blackboard实际上是一个UBlackboardData,而不是一个Component,BehaviorTree内部的Blackboard成员是UBlackboardData。Component用于AIController内,在AIController我们会声明一个UBlackboardComponent,而在Editor里边创建的是一个UBlackboardData,是不一样的数据结构,UBlackboardComponent的初始化函数InitializeBlackboard接受一个参数是UBlackboardData。
3.UBlackboardData是初始化UBlackboardComponent的参数数据,而我们之后的操作主要在UBlackboardComponent上完成。比如UBlackboardComponent的函数SetValueAsVector就是给Blackboard上的一个Vector参数赋值。
4.BehaviorTree和Blackboard比较类似,也是有一个UBehaviorTree类型和一个UBehaviorTreeComponent类型,主要操作位于UBehaviorTreeComponent上,UBehaviorTree内只是数据。比如UBehaviorTreeComponent的一个函数是StartTree,而参数是UBehaviorTree。
5.可见Component一般实现逻辑,而需要用到的数据都是另一种类型。我们一般把数据部分,就是UBehaviorTree和UBlackboardData放在Character中,而把对应的两个Component放在AIController中,每次使用AIController调用自己Pawn内部的UBlackboardData和UBehaviorTree。这样就可以把操作和数据分离,达到Controller的复用。
6.需要使用UBehaviorTreeComponent或者UBlackboardComponent的地方需要添加必要的头文件。
/* AI Specific includes */ #include "BehaviorTree/BehaviorTree.h" #include "BehaviorTree/BehaviorTreeComponent.h" #include "BehaviorTree/BlackboardComponent.h"
这比较奇怪,因为直接声明Component是可以识别的,但是声明是不完整的,大概是因为默认include里边只有class声明没有实现吧。因为class有声明只是没实现,所以这些include可以加到cpp里,不用加到h里。遇到类型不完整都可以试试加入相应头文件来解决。
还要注意一点,要更改控制build的c#文件里代码,加一个AIModule进去,这样UE在build的时候才会把AI相关模块build进去。加了这一个模块之后,build时间也显著增加了。
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "AIModule" });
下面介绍一下AI逻辑和记忆的编程方法:
1.在Editor内创建AIController,AICharacter,BehaviorTree,Blackboard文件,并把Blackboard指认给BehaviorTree内部的存储字段,把AIController指认给AICharacter作为操纵者。
2.首先在AICharacter内声明一个UBehaviorTree字段,注意UBlackboardData是包含在内部的。然后在Editor里边给他指认一个BehaviorTree。
3.在AIController内部声明两个UBlackboardComponent和UBehaviorTreeComponent字段。
4.初始化两个Component字段,首先使用CreateDefaultSubobject初始化内存,之后使用
//初始化UBlackboardComponent,把他和一个UBlackboardData联系起来。UBlackboardData取自Pawn的BehaviorTree的内部。 BlackboardComp->InitializeBlackboard(*GetPawn()->BehaviorTree->UBlackboardData); //UBehaviorTreeComponent不需要initialize,可以直接start一个Tree,参数就是你要start的tree,当然就是Pawn的那个字段了 BehaviorComp->StartTree(*GetPawn()->BehaviorTree);
5.之后如果AI的记忆要更变,就对UBlackboardComponent进行操作,它会对自己连接的Blackboard进行更改
//这里更改了一个Blackboard内部的Vector参数,作为AI跟踪的目的地。 BlackboardComp->SetValueAsVector(FName(“TargetLocation”), XXX->GetActorLocation());
6.AI的初始化和记忆更新写好之后,就是写AI逻辑的时候了,这关系到Editor里的BehaviorTree文件。BehaviorTree文件的编程方法和Blueprint类似,都是node连pin的。
具体关于BehaviorTree怎么用详见另一个文档。
相关文章推荐
- c语言学习笔记(11)宏定义使用与分析
- 2015-10-10 OC语言中的继承
- 黑马程序员——C语言学习笔记01 一部分容易忽视的概念
- 【cpp】【函数】
- c++ primer学习笔记4_复合类型续
- leetcode笔记:Implement strStr()
- C语言数组与指针详解(转载)
- C++学习笔记4 - 符合类型
- c++代理模式
- ACM输入输出--多组测试用例--C、C++、Java
- C语言,有N个硬币面值为a[1]...a[N],给一个非负数m,用这些硬币凑成m,求有多少种方法?
- 你会解吗? ?+?+?=30 把下面数字填到框里 (1,3,5,7,9,11,13,15)
- unix time stamp(时间戳)和常规时间相互转换的C++代码
- 排序矩阵(杨氏矩阵)中的从小到大第k个数(C++)
- C++Primer第五版 练习11.23(解答)
- 在C语言中 宏定义是什么?
- C++primer第五版笔记-第九章顺序容器
- C++Primer第五版 练习11.20(解答)
- C++Primer第五版 11.3.2节练习
- 关于析构函数的问题