Can't localize asset that is referenced in blueprint

Hi,

I have custom class containing localized fields. This class is derived from UObject and it’s instances are stored as assets (created through UFactory).

I’ve tried to reference this assets in a blueprint object so that I can extract FText fields from it (cleaner solution than having lots of localized fields in blueprint). Unfortunately GatherTextFromAssetsCommandlet wont process my “localization” asset. If asset is not referenced it’s gathered as expected.

Is this a correct behaviour?

Engine version 4.6.0

This is custom class is native, right? Are the FText members of the class marked up with UPROPERTY? They must be in order to be gathered - the gather system looks at the UPropertys of the UClass of an asset in a package to figure out if it has FText instances that require gathering, then gather them.

“If asset is not referenced it’s gathered as expected.” Sorry, I don’t understand what you mean. The default values of the class should be gathered. Any instances of the class should have their FText instances gathered too (IE: in a map).

This is native class that has fields marked up with UPROPERTY.

Class declaration looks somewhat like this:

USTRUCT(Blueprintable)
struct FLocalizeData
{
	GENERATED_USTRUCT_BODY()

public:
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = Default)
	FText Text;
	
	//... additional fields
};

UCLASS(hidecategories = Object)
class ULocalizeThis : public UObject
{
	GENERATED_UCLASS_BODY()

public:
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = Default)
	TArray<FLocalizeData> Definitions;
};

‘ULocalizeThis’ is the class from which I create asset (X) in editor. Then I make a blueprint class (B) with member variable of type ‘ULocalizeThis’. If this field holds reference to ‘ULocalizeThis’ asset (X), this asset (X) will be skiped during localization process.

Your code looks about right to me.

So you create an asset X of type ULocalizeThis and populate Definitions with values. Your blueprint B has an asset reference to your asset X - this bit should make absolutely no difference.

Asset X’s text isn’t appearing in your manifest files only when blueprint B references asset X? Otherwise, its text does appear in the manifest?

Yes. Text appears in manifest when asset is not referenced in blueprint. When it’s referenced text doesn’t appear.

When I was looking for the source of this behavior I found that asset package was failing (when unwanted behavior conditions where met) one of this tests in GatherTextFromAssetsCommandlet.cpp (I don’t remember which one. I’m sorry.) :

if( PackageSummary.PackageFlags & PKG_RequiresLocalizationGather || PackageSummary.GetFileVersionUE4() < VER_UE4_PACKAGE_REQUIRES_LOCALIZATION_GATHER_FLAGGING )

if( Package->RequiresLocalizationGather() )

I’m having trouble reproducing the issue. Could you zip up a simple reproduction case with the two packages (blueprint and asset) as well as the code for your asset’s class?

I’ve had trouble reproducing it also.

It looks like the problem lies in having implemented something in blueprint construction script. If blueprint doesn’t contain code in construction script, localization asset will be processed correctly.

Repro project is attached.

Localization asset class - ULocAssetDefinition. Zip file contains localization config file and Localization.bat as well, which can help you test this behaviour (requires modifying path variables in batch file)

Thanks for this. I’ve been taking a look and there’s definitely something weird going on.

It seems as though the process of loading blueprint B referencing asset B does something to asset B, a partial load, which is somehow causing asset B to not have the “requires localization” flag when asset B is loaded on its own. The presence of a node in blueprint B is causing it to be considered for localization, for some reason. Blueprint A lacks any nodes and isn’t even considered for localization - if it was, it too might cause asset A to fail to be gathered from.

Thanks for bringing this to our attention. The reproduction case was extremely useful. The issue is resolved with change list 2399207.

The gist of it is that asset B was loaded when explicitly loading blueprint B, then asset B was explicitly loaded, after having been loaded earlier. Both of those load operations for asset B follow a different code path than when asset B is loaded on its own. With this change list, Package->RequiresLocalizationGather() will have the proper result even after the redundant load.

Tangentially, I’d recommend using the manifest dependencies functionality (setting for gather commandlets) to make sure you’re not getting duplicate entries from the Engine or Editor in your own manifest.

Thank you for the fix and suggestion :slight_smile: