UE AI里的感知实现流程解析
感知与被感知流程
刺激源的配置与注册
配置结构
UPROPERTY(EditAnywhere, Category = "AI Perception", BlueprintReadOnly)
TArray<TSubclassOf<UAISense> > RegisterAsSourceForSenses;
向刺激源组件UAIPerceptionStimuliSourceComponent
中添加配置
注册刺激配置到感知系统
- 重写父类里的
OnRegister
函数,过滤掉RegisterAsSourceForSenses
里无效的配置,根据bAutoRegisterAsSource
的成员变量控制是否自注册到感知系统 bAutoRegisterAsSource
如果为true则执行RegisterWithPerceptionSystem
函数,该函数首先拿到感知系统实例指针,然后迭代配置结构中的UAISense
调用感知系统中的RegisterSourceForSenseClass
来完成刺激源Sense的注册及刺激源组件持有者的注册
感知组件的配置、注册、与信息更新
感知配置项
UPROPERTY(EditDefaultsOnly, Instanced, Category = "AI Perception")
TArray<TObjectPtr<UAISenseConfig>> SensesConfig;
这是感知类型配置,与刺激源配置不同的是,感知配置对UAISense进行了封装,里面添加了感知间隔的有效时间(Age),调试颜色控制,开启允许与否的控制等
注册感知配置到感知系统
- 同样的配方,在重写的
OnRegister
函数里进行处理,首先在持有者AIController的OnEndPlay
委托上绑定OnOwnerEndPlay
函数,该函数用于在AIController玩法结束时取消所有的感知系统里的感知注册 - 循环
SensesConfig
调用RegisterSenseConfig函数,该函数首先对SenseConfig进行脱壳,获取UAISense
,然后调用感知系统的RegisterSenseClass
函数注册UAISense配置,这个配置与刺激源注册配置是一致的 - 添加感知组件的
PerceptionFilter
白名单 - 设置刺激源留存的最大有效间隔时间(Age),这个留存时间保留在
TArray<float> MaxActiveAge
里,这个数组的索引与SenseID保持一致 - 最后一步是调用感知系统的
UpdateListener
函数来完成在感知系统中的感知注册,该函数做了以下处理:
- 检查当前传入的Listener是否有效,如果有效,则说明传入的是已经注册过的Listener,那么调用
FPerceptionListener
的UpdateListenerProperties
函数来更新该Listener的teamid及感知白名单,再调用感知系统的OnListenerUpdate
函数,而该函数是迭代了已经注册的Senses配置实例,转调了Sense的OnListenerUpdat