bool UGameplayTagsManager::AddLeafTagToContainer(FGameplayTagContainer& TagContainer, FGameplayTag& Tag) { // Check tag is not already in container if (TagContainer.HasTag(Tag, EGameplayTagMatchType::Explicit, EGameplayTagMatchType::Explicit)) { return true; } // Check tag is not just a parent of an existing tag in the container for (auto It = TagContainer.CreateConstIterator(); It; ++It) { FGameplayTagContainer ParentTags = RequestGameplayTagParents(*It); if (ParentTags.HasTag(Tag, EGameplayTagMatchType::Explicit, EGameplayTagMatchType::Explicit)) { return false; } } // Remove any tags in the container that are a parent to this tag FGameplayTagContainer ParentTags = RequestGameplayTagParents(Tag); for (auto It = ParentTags.CreateConstIterator(); It; ++It) { if (TagContainer.HasTag(*It, EGameplayTagMatchType::Explicit, EGameplayTagMatchType::Explicit)) { TagContainer.RemoveTag(*It); } } // Add the tag TagContainer.AddTag(Tag); return true; }
void SGameplayTagWidget::VerifyAssetTagValidity() { FGameplayTagContainer LibraryTags; // Create a set that is the library of all valid tags TArray< TSharedPtr<FGameplayTagNode> > NodeStack; UGameplayTagsManager& TagsManager = IGameplayTagsModule::Get().GetGameplayTagsManager(); TagsManager.GetFilteredGameplayRootTags(TEXT(""), NodeStack); while (NodeStack.Num() > 0) { TSharedPtr<FGameplayTagNode> CurNode = NodeStack.Pop(); if (CurNode.IsValid()) { LibraryTags.AddTag(TagsManager.RequestGameplayTag(CurNode->GetCompleteTag())); NodeStack.Append(CurNode->GetChildTagNodes()); } } // Find and remove any tags on the asset that are no longer in the library for (int32 ContainerIdx = 0; ContainerIdx < TagContainers.Num(); ++ContainerIdx) { UObject* OwnerObj = TagContainers[ContainerIdx].TagContainerOwner.Get(); FGameplayTagContainer* Container = TagContainers[ContainerIdx].TagContainer; if (Container) { FGameplayTagContainer EditableContainer = *Container; FGameplayTagContainer InvalidTags; for (auto It = Container->CreateConstIterator(); It; ++It) { if (!LibraryTags.HasTag(*It, EGameplayTagMatchType::Explicit, EGameplayTagMatchType::Explicit)) { InvalidTags.AddTag(*It); } } if (InvalidTags.Num() > 0) { FString InvalidTagNames; for (auto InvalidIter = InvalidTags.CreateConstIterator(); InvalidIter; ++InvalidIter) { EditableContainer.RemoveTag(*InvalidIter); InvalidTagNames += InvalidIter->ToString() + TEXT("\n"); } SetContainer(Container, &EditableContainer, OwnerObj); FFormatNamedArguments Arguments; Arguments.Add(TEXT("Objects"), FText::FromString( InvalidTagNames )); FText DialogText = FText::Format( LOCTEXT("GameplayTagWidget_InvalidTags", "Invalid Tags that have been removed: \n\n{Objects}"), Arguments ); OpenMsgDlgInt( EAppMsgType::Ok, DialogText, LOCTEXT("GameplayTagWidget_Warning", "Warning") ); } } } }
void SGameplayTagWidget::OnTagUnchecked(TSharedPtr<FGameplayTagNode> NodeUnchecked) { FScopedTransaction Transaction( LOCTEXT("GameplayTagWidget_RemoveTags", "Remove Gameplay Tags")); if (NodeUnchecked.IsValid()) { UGameplayTagsManager& TagsManager = IGameplayTagsModule::Get().GetGameplayTagsManager(); for (int32 ContainerIdx = 0; ContainerIdx < TagContainers.Num(); ++ContainerIdx) { UObject* OwnerObj = TagContainers[ContainerIdx].TagContainerOwner.Get(); FGameplayTagContainer* Container = TagContainers[ContainerIdx].TagContainer; FGameplayTag Tag = TagsManager.RequestGameplayTag(NodeUnchecked->GetCompleteTag()); if (Container) { FGameplayTagContainer EditableContainer = *Container; EditableContainer.RemoveTag(Tag); TWeakPtr<FGameplayTagNode> ParentNode = NodeUnchecked->GetParentTagNode(); if (ParentNode.IsValid()) { // Check if there are other siblings before adding parent bool bOtherSiblings = false; for (auto It = ParentNode.Pin()->GetChildTagNodes().CreateConstIterator(); It; ++It) { Tag = TagsManager.RequestGameplayTag(It->Get()->GetCompleteTag()); if (EditableContainer.HasTag(Tag, EGameplayTagMatchType::Explicit, EGameplayTagMatchType::Explicit)) { bOtherSiblings = true; break; } } // Add Parent if (!bOtherSiblings) { Tag = TagsManager.RequestGameplayTag(ParentNode.Pin()->GetCompleteTag()); EditableContainer.AddTag(Tag); } } // Uncheck Children for (const auto& ChildNode : NodeUnchecked->GetChildTagNodes()) { UncheckChildren(ChildNode, EditableContainer); } SetContainer(Container, &EditableContainer, OwnerObj); } } } }
void SGameplayTagWidget::UncheckChildren(TSharedPtr<FGameplayTagNode> NodeUnchecked, FGameplayTagContainer& EditableContainer) { UGameplayTagsManager& TagsManager = IGameplayTagsModule::Get().GetGameplayTagsManager(); FGameplayTag Tag = TagsManager.RequestGameplayTag(NodeUnchecked->GetCompleteTag()); EditableContainer.RemoveTag(Tag); // Uncheck Children for (const auto& ChildNode : NodeUnchecked->GetChildTagNodes()) { UncheckChildren(ChildNode, EditableContainer); } }
void SGameplayTagWidget::OnTagChecked(TSharedPtr<FGameplayTagNode> NodeChecked) { FScopedTransaction Transaction( LOCTEXT("GameplayTagWidget_AddTags", "Add Gameplay Tags") ); UGameplayTagsManager& TagsManager = IGameplayTagsModule::Get().GetGameplayTagsManager(); for (int32 ContainerIdx = 0; ContainerIdx < TagContainers.Num(); ++ContainerIdx) { TWeakPtr<FGameplayTagNode> CurNode(NodeChecked); UObject* OwnerObj = TagContainers[ContainerIdx].TagContainerOwner.Get(); FGameplayTagContainer* Container = TagContainers[ContainerIdx].TagContainer; if (Container) { FGameplayTagContainer EditableContainer = *Container; bool bRemoveParents = false; while (CurNode.IsValid()) { FGameplayTag Tag = TagsManager.RequestGameplayTag(CurNode.Pin()->GetCompleteTag()); if (bRemoveParents == false) { bRemoveParents = true; if (bMultiSelect == false) { EditableContainer.RemoveAllTags(); } EditableContainer.AddTag(Tag); } else { EditableContainer.RemoveTag(Tag); } CurNode = CurNode.Pin()->GetParentTagNode(); } SetContainer(Container, &EditableContainer, OwnerObj); } } }