void FBlackboardDecoratorDetails::OnKeyIDChanged()
{
	CachedOperationType = EBlackboardKeyOperation::Basic;
	CachedKeyType = NULL;

	UBlackboardData* Blackboard = CachedBlackboardAsset.Get();
	if (Blackboard == NULL)
	{
		return;
	}

	uint8 KeyID;
	FPropertyAccess::Result Result = KeyIDProperty->GetValue(KeyID);
	if (Result == FPropertyAccess::Success)
	{
		const FBlackboardEntry* KeyEntry = Blackboard->GetKey(KeyID);
		if(KeyEntry && KeyEntry->KeyType)
		{
			CachedKeyType = KeyEntry->KeyType->GetClass();
			CachedOperationType = KeyEntry->KeyType->GetTestOperation();
		}
		else
		{
			CachedKeyType = nullptr;
			CachedOperationType = 0;
		}
	}

	// special handling of enum type: cache all names for combo box (display names)
	UEnum* SelectedEnumType = NULL;
	if (CachedKeyType == UBlackboardKeyType_Enum::StaticClass())
	{
		const FBlackboardEntry* EntryInfo = Blackboard->GetKey(KeyID);
		SelectedEnumType = ((UBlackboardKeyType_Enum*)(EntryInfo->KeyType))->EnumType;
	}
	else if (CachedKeyType == UBlackboardKeyType_NativeEnum::StaticClass())
	{
		const FBlackboardEntry* EntryInfo = Blackboard->GetKey(KeyID);
		SelectedEnumType = ((UBlackboardKeyType_NativeEnum*)(EntryInfo->KeyType))->EnumType;
	}

	if (SelectedEnumType)
	{
		CachedCustomObjectType = SelectedEnumType;
		EnumPropValues.Reset();

		if (CachedCustomObjectType)
		{
			for (int32 i = 0; i < CachedCustomObjectType->NumEnums() - 1; i++)
			{
				FString DisplayedName = CachedCustomObjectType->GetEnumText(i).ToString();
				EnumPropValues.Add(DisplayedName);
			}
		}
	}
}
//----------------------------------------------------------------------//
// FBlackboardKeySelector
//----------------------------------------------------------------------//
void FBlackboardKeySelector::ResolveSelectedKey(const UBlackboardData& BlackboardAsset)
{
	if (SelectedKeyName.IsNone() == false || !bNoneIsAllowedValue)
	{
		if (SelectedKeyName.IsNone() && !bNoneIsAllowedValue)
		{
			InitSelection(BlackboardAsset);
		}

		SelectedKeyID = BlackboardAsset.GetKeyID(SelectedKeyName);
		SelectedKeyType = BlackboardAsset.GetKeyType(SelectedKeyID);
	}
}
void FBlackboardSelectorDetails::OnKeyComboChange(int32 Index)
{
	if (KeyValues.IsValidIndex(Index))
	{
		UBlackboardData* BlackboardAsset = CachedBlackboardAsset.Get();
		if (BlackboardAsset)
		{
			const uint8 KeyID = BlackboardAsset->GetKeyID(KeyValues[Index]);
			const UObject* KeyClass = BlackboardAsset->GetKeyType(KeyID);

			MyKeyClassProperty->SetValue(KeyClass);
			MyKeyIDProperty->SetValue(KeyID);

			MyKeyNameProperty->SetValue(KeyValues[Index]);
		}
	}
}
예제 #4
0
bool AAIController::InitializeBlackboard(UBlackboardComponent& BlackboardComp, UBlackboardData& BlackboardAsset)
{
    check(BlackboardComp.GetOwner() == this);

    if (BlackboardComp.InitializeBlackboard(BlackboardAsset))
    {
        // find the "self" key and set it to our pawn
        const FBlackboard::FKey SelfKey = BlackboardAsset.GetKeyID(FBlackboard::KeySelf);
        if (SelfKey != FBlackboard::InvalidKey)
        {
            BlackboardComp.SetValue<UBlackboardKeyType_Object>(SelfKey, GetPawn());
        }

        OnUsingBlackBoard(&BlackboardComp, &BlackboardAsset);
        return true;
    }
    return false;
}
bool UMyBlackboardComponent::PushBlackboard(UBlackboardData* NewAsset, TArray<struct FBlackboardKeySelector> &Params)
{

	UAISystem* AISystem = UAISystem::GetCurrentSafe(GetWorld());
	if (AISystem == nullptr)
	{
		return false;
	}

	//makes a copy of the blackboard
	//otherwise the data in the bb can be owerwritten by other calls or other instances
	UBlackboardData* NewAssetCopy = CopyBlackboardData(NewAsset);

	//save current bb on stack
	BBStack.Add(BlackboardAsset);
	UBlackboardData* OldAsset = BlackboardAsset;

	//and replace it by new bb
	BlackboardAsset = NewAssetCopy;



	bool bSuccess = true;
	const int32 NumKeys = NewAssetCopy->Keys.Num();

	//make old bb parent of new bb
	NewAssetCopy->Parent = OldAsset;
	//update first key id accordingly
	NewAssetCopy->UpdateKeyIDs();


	TArray<FBlackboardInitializationData> InitList;

	InitList.Reserve(NumKeys);

	//grow ValueOffsets to contain new bb offsets
	ValueOffsets.AddZeroed(NumKeys);

	for (int32 KeyIndex = 0; KeyIndex < NumKeys; KeyIndex++)
	{
		if (NewAssetCopy->Keys[KeyIndex].KeyType)
		{
			InitList.Add(FBlackboardInitializationData(KeyIndex + NewAssetCopy->GetFirstKeyID(), NewAssetCopy->Keys[KeyIndex].KeyType->GetValueSize()));
		}
	}

	
	// sort key values by memory size, so they can be packed better
	// it still won't protect against structures, that are internally misaligned (-> uint8, uint32)
	// but since all Engine level keys are good... 
	InitList.Sort(FBlackboardInitializationData::FMemorySort());
	uint16 MemoryOffset = 0;
	for (int32 Index = 0; Index < InitList.Num(); Index++)
	{
		ValueOffsets[InitList[Index].KeyID] = MemoryOffset + ValueMemory.Num();
		MemoryOffset += InitList[Index].DataSize;
	}

	//grow ValueMemory to contain new bb data
	//(also allows memory for parameters, this is not really neaded, to improve...)
	ValueMemory.AddZeroed(MemoryOffset);

	// initialize memory
	for (int32 Index = 0; Index < InitList.Num(); Index++)
	{
		const FBlackboardEntry* KeyData = BlackboardAsset->GetKey(InitList[Index].KeyID);
		uint8* RawData = GetKeyRawData(InitList[Index].KeyID);

		KeyData->KeyType->Initialize(RawData);
	}

	int32 ParamIndex = 0;
	for (int32 KeyIndex = 0; KeyIndex < NumKeys && ParamIndex<Params.Num(); KeyIndex++)
	{
		//for each parameter
		if (NewAssetCopy->Keys[KeyIndex].KeyType&&NewAssetCopy->Keys[KeyIndex].EntryName.ToString().StartsWith("PARAM_"))
		{

			FBlackboard::FKey ParentKeyID = OldAsset->GetKeyID(Params[ParamIndex].SelectedKeyName);
			FBlackboard::FKey ChildKeyID = BlackboardAsset->GetKeyID(BlackboardAsset->Keys[KeyIndex].EntryName);
			if (ParentKeyID != FBlackboard::InvalidKey && ChildKeyID != FBlackboard::InvalidKey)
			{

				//redirect ValueOffset to the memory location of the actual argument
				ValueOffsets[ChildKeyID] = ValueOffsets[ParentKeyID];

				//add observer to propagate notifications to actual argument observers
				DelegateHandles.Add(FMyKeyDelegate(ChildKeyID, RegisterObserver(ChildKeyID, this, FOnBlackboardChange::CreateLambda([this, ParentKeyID](const UBlackboardComponent& BComp, FBlackboard::FKey ChangedKeyID){
					this->CallNotifyObservers(ParentKeyID);
				}))));

				ParamIndex++;
			}

		}

	}

	//saves number of parameters found
	ParamsNumStack.Add(ParamIndex);

	return bSuccess;
}