Still problem here. Missing String Tables show and localization dashboard cannot gather texts
I was having a similar issue (and confusion) on earlier versions, is this code still of use?
Confusion with String Table localization, c++ - #3 by Roy_Wierer.Seda145
I am on 4.2, gathered the texts, confirmed that they are there, and yet these specific texts do not show up and i also did the GameInstance BP change to the locale I gathered (“en”)
Hmm, i restarted the project, collected the texts again, Editor got stuck while I tried to edit the translations just to look at what it gathhered, so then I restarted the editor again, and now it works.
So many bugs in this crucial system
This needs to be solved ASAP. So many marketplace plugins can’t update to 5.4 because of it.
It was finally fixed in 5.4.2!
Is this an issue in 5.3? Or is it only meant to be a problem for 5.4? Because I’m having the same problem on 5.3 outside of data tables…
Update: It needs a “/” at the very start.
I solved this for me by adding the folder where my tables were to my packaging. Please let me know if this is a bad idea, but nothing else seems to fix it.
That’s actually required for them to be loaded if not referenced elsewhere (by a pointer in a UAsset). Otherwise you will get missing strings when attempting to localize from code, say by calling "FText::FromStringTable(InStringTableId, InKey)"
A “reference” from c++ does not count. For this reason I prefer to just add my string tables (and datatables too) directly from c++ to the scan settings, done from C++ like this:
/**Copyright: Roy Wierer (Ferrefy). All Rights Reserved.**/
#include "AssetUtils.h"
#include "Modules/ModuleManager.h"
#include "PropertyEditorModule.h"
#include "PropertyEditorDelegates.h"
#include "Settings/ProjectPackagingSettings.h"
#include "Engine/AssetManagerSettings.h"
void UAssetUtils::AddDirectoryToScanAndCook(const FString& InDirectory, const FName& InAssetType, const TSoftClassPtr<UObject> InAssetBaseClass) {
UProjectPackagingSettings* PackagingSettings = GetMutableDefault<UProjectPackagingSettings>();
check(IsValid(PackagingSettings));
// For whatever reason the datatype required is a poorly implemented directory one, containing just a string path.
const FDirectoryPath* PathX = PackagingSettings->DirectoriesToAlwaysCook.FindByPredicate([&InDirectory](const FDirectoryPath& PathX) { return PathX.Path == InDirectory; });
if (PathX == nullptr) {
FDirectoryPath NewPath = FDirectoryPath();
NewPath.Path = InDirectory;
PackagingSettings->DirectoriesToAlwaysCook.Add(NewPath);
}
UAssetManagerSettings* AssetManagerSettings = GetMutableDefault<UAssetManagerSettings>();
check(IsValid(AssetManagerSettings));
check(!InAssetBaseClass.IsNull());
/*
* The following error appears when managing assets in the asset manager which don't implement GetPrimaryAssetID, which is oddly.... the datatable and string table.
* [UE5.1.1] LogAssetManager: Error: Registered PrimaryAssetId DataTable:DT_XXXX for asset /SomePlugin/DT_XXXX.XXXX does not match object’s real id of ! This will not load properly at runtime!
* Setting the bShouldManagerDetermineTypeAndName to true works around this.
*/
AssetManagerSettings->bShouldManagerDetermineTypeAndName = true;
/**
* Note that there can only be one entry in the array per type, so merge the rules into an existing one:
* LogAssetManager: Error: Found multiple "StringTable" Primary Asset Type entries in "Primary Asset Types To Scan" config. Only a single entry per type is supported.
*/
FPrimaryAssetTypeInfo* ExistingInfo = AssetManagerSettings->PrimaryAssetTypesToScan.FindByPredicate([&InAssetType](const FPrimaryAssetTypeInfo& InfoX) { return InfoX.PrimaryAssetType == InAssetType; });
if (ExistingInfo == nullptr) {
FPrimaryAssetTypeInfo NewInfo = FPrimaryAssetTypeInfo();
NewInfo.PrimaryAssetType = InAssetType;
NewInfo.SetAssetBaseClass(InAssetBaseClass);
FDirectoryPath NewDir = FDirectoryPath();
NewDir.Path = InDirectory;
NewInfo.GetDirectories().Add(NewDir);
NewInfo.Rules.CookRule = EPrimaryAssetCookRule::AlwaysCook;
AssetManagerSettings->PrimaryAssetTypesToScan.Add(NewInfo);
}
else {
// See if the directory exists already and return if so.
if (ExistingInfo->GetDirectories().ContainsByPredicate([&InDirectory](const FDirectoryPath& PathX) { return PathX.Path == InDirectory; })) {
return;
}
// Let's not assume there is an existing entry with valid data, just because we can. Set the properties we need.
//ExistingInfo->PrimaryAssetType = InAssetType; // We already know this is set.
ExistingInfo->SetAssetBaseClass(InAssetBaseClass);
FDirectoryPath NewDir = FDirectoryPath();
NewDir.Path = InDirectory;
ExistingInfo->GetDirectories().Add(NewDir);
ExistingInfo->Rules.CookRule = EPrimaryAssetCookRule::AlwaysCook;
}
}
And called like this:
/**Copyright: Roy Wierer (Ferrefy). All Rights Reserved.**/
#include "CustomSettingsPluginEditorInstaller.h"
#include "AssetUtils.h"
#include "Engine/DataTable.h"
#include "Internationalization/StringTable.h"
// Setup
void FCustomSettingsPluginEditorInstaller::RunAutomatedInstaller() {
UAssetUtils::AddDirectoryToScanAndCook(TEXT("/CustomSettingsPlugin/Localization/Text"), TEXT("StringTable"), UStringTable::StaticClass());
UAssetUtils::AddDirectoryToScanAndCook(TEXT("/CustomSettingsPlugin/Data/DataTables"), TEXT("DataTable"), UDataTable::StaticClass());
}
Users just localizing UI through a text node in a UAsset (selecting a datatable and key) should not have to go through all that, since their node references the string table for them.