Exemplo n.º 1
0
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;
}