@寒江独钓
@2014.3.29
其关键代码在ShooterAIController.cpp中实现,当然有其父类与其他相关联的类.
当创建bot时,显然需要bot的控制类与肉身类,在UE4中是Controller类与APawn类,这点与UE3十分类似.并会通过Possess方法将两者关联[也即灵魂占有肉身,就像鬼片里演的一样].这里会调用控制类的构造函数:
AShooterAIController::AShooterAIController(constclass FPostConstructInitializeProperties& PCIP) : Super(PCIP)
{
BlackboardComp= PCIP.CreateDefaultSubobject
BehaviorComp= PCIP.CreateDefaultSubobject
bWantsPlayerState= true;
}
为了使用行为树与黑板,这里先前就创建了两个组件.之后,在创建控制类对象后,需要占”有”操作.
void AShooterAIController::Possess(APawn*InPawn)
{
Super::Possess(InPawn);
AShooterBot*Bot = Cast
//start behavior
if(Bot && Bot->BotBehavior)
{
BlackboardComp->InitializeBlackboard(Bot->BotBehavior->BlackboardAsset);
EnemyKeyID= BlackboardComp->GetKeyID("Enemy");
NeedAmmoKeyID= BlackboardComp->GetKeyID("NeedAmmo");
BehaviorComp->StartTree(Bot->BotBehavior);
}
}
这里主要做了possess动作,还将黑板用编辑器创建的黑板资源初始化,并启动执行行为树.
Bot 与 Bot->BotBehavior,Bot即为NPC的肉身, Bot->BotBehavior即为其行为树,在自定义类中定义,但其赋值却在编辑器中可视化编辑.
class AShooterBot : public AShooterCharacter
{
GENERATED_UCLASS_BODY()
UPROPERTY(EditAnywhere,Category=Behavior)
classUBehaviorTree* BotBehavior;
virtualbool IsFirstPerson() const OVERRIDE;
virtualvoid FaceRotation(FRotator NewRotation, float DeltaTime = 0.f) OVERRIDE;
};
行为树实现如下:
这颗行为树还是较为简单的,主要增加了几个装饰器,显得高端了点而已.
黑板资源设置如下所示,可以看出,黑板内容十分简单,无非是些Map,关键是其内存管理,当然UE4已经封装好了,可以直接用之.其实现对程序员来说说是有参考价值的.我之前实现的黑板就存在内存泄露问题.
之后,黑板就可以很容易被利用,以下是读写示例.
void AShooterAIController::CheckAmmo(constclass AShooterWeapon* CurrentWeapon)
{
……
BlackboardComp->SetValueAsBool(NeedAmmoKeyID,(Ratio <= 0.1f));
}
void AShooterAIController::SetEnemy(classAPawn* InPawn)
{
…
BlackboardComp->SetValueAsObject(EnemyKeyID,InPawn);
}
class AShooterCharacter* AShooterAIController::GetEnemy()const
{
…
returnCast
}
之后,我们的NPC便由我们的行为树来控制,而不是UE3的FSM.游戏每个Tick都会去执行行为树,找到满足条件的动作节点去执行.
that’s all,thank you!