void UGameplayTagsManager::ConstructGameplayTagTree() { if (!GameplayRootTag.IsValid()) { GameplayRootTag = MakeShareable(new FGameplayTagNode()); { #if STATS FString PerfMessage = FString::Printf(TEXT("UGameplayTagsManager::ConstructGameplayTagTree: Construct from data asset")); SCOPE_LOG_TIME_IN_SECONDS(*PerfMessage, nullptr) #endif for (auto It(GameplayTagTables.CreateIterator()); It; It++) { if (*It) { PopulateTreeFromDataTable(*It); } } } if (ShouldImportTagsFromINI()) { #if STATS FString PerfMessage = FString::Printf(TEXT("UGameplayTagsManager::ConstructGameplayTagTree: ImportINI")); SCOPE_LOG_TIME_IN_SECONDS(*PerfMessage, nullptr) #endif // Update path: Check for old tags in DefaultEngine.ini (we'll push them to the UGameplayTagSettings class). TArray<FString> EngineConfigTags; GConfig->GetArray(TEXT("/Script/GameplayTags.GameplayTagsSettings"), TEXT("GameplayTags"), EngineConfigTags, GEngineIni); if (EngineConfigTags.Num() > 0) { UGameplayTagsSettings* MutableDefault = GetMutableDefault<UGameplayTagsSettings>(); if (MutableDefault->GameplayTags.Num() == 0) { MutableDefault->GameplayTags.Append(EngineConfigTags); } } // Load any GameplayTagSettings from config (their default object) for (TObjectIterator<UClass> ClassIt; ClassIt; ++ClassIt) { UClass* Class = *ClassIt; if (!Class->IsChildOf<UGameplayTagsSettings>() || Class->HasAnyClassFlags(CLASS_Abstract)) { continue; } #if WITH_EDITOR Class->GetDefaultObject<UGameplayTagsSettings>()->SortTags(); #endif for (FString TagStr : Class->GetDefaultObject<UGameplayTagsSettings>()->GameplayTags) { FGameplayTagTableRow TableRow; TableRow.Tag = TagStr; AddTagTableRow(TableRow); } } GameplayRootTag->GetChildTagNodes().Sort(FCompareFGameplayTagNodeByTag()); } if (ShouldUseFastReplication()) { #if STATS FString PerfMessage = FString::Printf(TEXT("UGameplayTagsManager::ConstructGameplayTagTree: Reconstruct NetIndex")); SCOPE_LOG_TIME_IN_SECONDS(*PerfMessage, nullptr) #endif ConstructNetIndex(); } { #if STATS FString PerfMessage = FString::Printf(TEXT("UGameplayTagsManager::ConstructGameplayTagTree: GameplayTagTreeChangedEvent.Broadcast")); SCOPE_LOG_TIME_IN_SECONDS(*PerfMessage, nullptr) #endif GameplayTagTreeChangedEvent.Broadcast(); } // Update the TagRedirects map TagRedirects.Empty(); FConfigSection* PackageRedirects = GConfig->GetSectionPrivate(TEXT("/Script/Engine.Engine"), false, true, GEngineIni); for (FConfigSection::TIterator It(*PackageRedirects); It; ++It) { if (It.Key() == TEXT("GameplayTagRedirects")) { FName OldTagName = NAME_None; FName NewTagName; if (FParse::Value(*It.Value(), TEXT("OldTagName="), OldTagName)) { if (FParse::Value(*It.Value(), TEXT("NewTagName="), NewTagName)) { if (ensureMsgf(!TagRedirects.Contains(OldTagName), TEXT("Old tag %s is being redirected to more than one tag. Please remove all the redirections except for one."), *OldTagName.ToString())) { FGameplayTag OldTag = RequestGameplayTag(OldTagName, false); //< This only succeeds if OldTag is in the Table! if (OldTag.IsValid()) { UE_LOG(LogGameplayTags, Warning, TEXT("Old tag (%s) which is being redirected still exists in the table! Generally you should " TEXT("remove the old tags from the table when you are redirecting to new tags, or else users will ") TEXT("still be able to add the old tags to containers.")), *OldTagName.ToString() ); } FGameplayTag NewTag = (NewTagName != NAME_None) ? RequestGameplayTag(NewTagName, false) : FGameplayTag(); if (!NewTag.IsValid() && NewTagName != NAME_None) { UE_LOG(LogGameplayTags, Warning, TEXT("Invalid new tag %s! Cannot replace old tag %s."), *NewTagName.ToString(), *OldTagName.ToString()); } else { // Populate the map TagRedirects.Add(OldTagName, NewTag); } } } } } } }
void UGameplayTagsManager::ConstructGameplayTagTree() { if (!GameplayRootTag.IsValid()) { GameplayRootTag = MakeShareable(new FGameplayTagNode()); { #if STATS FString PerfMessage = FString::Printf(TEXT("UGameplayTagsManager::ConstructGameplayTagTree: Construct from data asset")); SCOPE_LOG_TIME_IN_SECONDS(*PerfMessage, nullptr) #endif for (auto It(GameplayTagTables.CreateIterator()); It; It++) { if (*It) { PopulateTreeFromDataTable(*It); } } } if (ShouldImportTagsFromINI()) { #if STATS FString PerfMessage = FString::Printf(TEXT("UGameplayTagsManager::ConstructGameplayTagTree: ImportINI")); SCOPE_LOG_TIME_IN_SECONDS(*PerfMessage, nullptr) #endif // Update path: Check for old tags in DefaultEngine.ini (we'll push them to the UGameplayTagSettings class). TArray<FString> EngineConfigTags; GConfig->GetArray(TEXT("/Script/GameplayTags.GameplayTagsSettings"), TEXT("GameplayTags"), EngineConfigTags, GEngineIni); if (EngineConfigTags.Num() > 0) { UGameplayTagsSettings* MutableDefault = GetMutableDefault<UGameplayTagsSettings>(); if (MutableDefault->GameplayTags.Num() == 0) { MutableDefault->GameplayTags.Append(EngineConfigTags); } } // Load any GameplayTagSettings from config (their default object) for (TObjectIterator<UClass> ClassIt; ClassIt; ++ClassIt) { UClass* Class = *ClassIt; if (!Class->IsChildOf<UGameplayTagsSettings>() || Class->HasAnyClassFlags(CLASS_Abstract)) { continue; } #if WITH_EDITOR Class->GetDefaultObject<UGameplayTagsSettings>()->SortTags(); #endif for (FString TagStr : Class->GetDefaultObject<UGameplayTagsSettings>()->GameplayTags) { FGameplayTagTableRow TableRow; TableRow.Tag = TagStr; AddTagTableRow(TableRow); } } GameplayRootTag->GetChildTagNodes().Sort(FCompareFGameplayTagNodeByTag()); } if (ShouldUseFastReplication()) { #if STATS FString PerfMessage = FString::Printf(TEXT("UGameplayTagsManager::ConstructGameplayTagTree: Reconstruct NetIndex")); SCOPE_LOG_TIME_IN_SECONDS(*PerfMessage, nullptr) #endif ConstructNetIndex(); } { #if STATS FString PerfMessage = FString::Printf(TEXT("UGameplayTagsManager::ConstructGameplayTagTree: GameplayTagTreeChangedEvent.Broadcast")); SCOPE_LOG_TIME_IN_SECONDS(*PerfMessage, nullptr) #endif GameplayTagTreeChangedEvent.Broadcast(); } }