void UAIPerceptionComponent::OnRegister() { Super::OnRegister(); bCleanedUp = false; AActor* Owner = GetOwner(); if (Owner != nullptr) { Owner->OnEndPlay.AddUniqueDynamic(this, &UAIPerceptionComponent::OnOwnerEndPlay); AIOwner = Cast<AAIController>(Owner); } UAIPerceptionSystem* AIPerceptionSys = UAIPerceptionSystem::GetCurrent(GetWorld()); if (AIPerceptionSys != nullptr) { PerceptionFilter.Clear(); if (SensesConfig.Num() > 0) { // set up perception listener based on SensesConfig for (auto SenseConfig : SensesConfig) { if (SenseConfig) { TSubclassOf<UAISense> SenseImplementation = SenseConfig->GetSenseImplementation(); if (SenseImplementation) { // make sure it's registered with perception system AIPerceptionSys->RegisterSenseClass(SenseImplementation); if (SenseConfig->IsEnabled()) { PerceptionFilter.AcceptChannel(UAISense::GetSenseID(SenseImplementation)); } const FAISenseID SenseID = UAISense::GetSenseID(SenseImplementation); check(SenseID.IsValid()); SetMaxStimulusAge(SenseID, SenseConfig->GetMaxAge()); } } } AIPerceptionSys->UpdateListener(*this); } } // this should not be needed but aparently AAIController::PostRegisterAllComponents // gets called component's OnRegister AAIController* AIOwner = Cast<AAIController>(GetOwner()); if (AIOwner) { AIOwner->PerceptionComponent = this; } }
FAISenseID UAIPerceptionSystem::RegisterSenseClass(TSubclassOf<UAISense> SenseClass) { check(SenseClass); FAISenseID SenseID = UAISense::GetSenseID(SenseClass); if (SenseID.IsValid() == false) { UAISense* SenseCDO = GetMutableDefault<UAISense>(SenseClass); SenseID = SenseCDO->UpdateSenseID(); if (SenseID.IsValid() == false) { // @todo log a message here return FAISenseID::InvalidID(); } } if (SenseID.Index >= Senses.Num()) { const int32 ItemsToAdd = SenseID.Index - Senses.Num() + 1; Senses.AddZeroed(ItemsToAdd); #if !UE_BUILD_SHIPPING DebugSenseColors.AddZeroed(ItemsToAdd); #endif } if (Senses[SenseID] == nullptr) { Senses[SenseID] = NewObject<UAISense>(this, SenseClass); check(Senses[SenseID]); bHandlePawnNotification |= Senses[SenseID]->ShouldAutoRegisterAllPawnsAsSources() || Senses[SenseID]->WantsNewPawnNotification(); if (Senses[SenseID]->ShouldAutoRegisterAllPawnsAsSources()) { UWorld* World = GetWorld(); if (World->HasBegunPlay()) { RegisterAllPawnsAsSourcesForSense(SenseID); } // otherwise it will get called in StartPlay() } #if !UE_BUILD_SHIPPING DebugSenseColors[SenseID] = Senses[SenseID]->GetDebugColor(); PerceptionDebugLegend += Senses[SenseID]->GetDebugLegend(); // make senses v-log to perception system's log REDIRECT_OBJECT_TO_VLOG(Senses[SenseID], this); UE_VLOG(this, LogAIPerception, Log, TEXT("Registering sense %s"), *Senses[SenseID]->GetName()); #endif } return SenseID; }