FNAME_Find is supposed to return NAME_None (or FName() which == NAME_None) if the string is not found.
Constructing the FName eventually ends up here in UnrealNames.cpp (see below). This function ignores FindType completely and constructs an FName containing “None” but with the InternalNumber set - in the example case above “ThisDoesNotExist_2” sets the InternalNumber to 2. This causes comparisons with NAME_None and the function IsNone() to be false.
static FName MakeWithNumber(FNameEntryIds BaseIds, EFindName FindType, int32 InternalNumber) { #if UE_FNAME_OUTLINE_NUMBER ...not important because UE_FNAME_OUTLINE_NUMBER==0 ... #else // Number is just stored in the FName pass it straight on return FinalConstruct(BaseIds, InternalNumber); #endif }
Steps to Reproduce
Try this code - this was tested in an editor build which enables FName case preservation but should not affect FNAME_Find. We’d expect all the checks to succeed but the checks on TEST2 fail.
FName TEST1(TEXT(“ThisDoesNotExist”), FNAME_Find);
check(TEST1 == NAME_None);
check(TEST1.IsNone());
FName TEST2(TEXT(“ThisDoesNotExist_2”), FNAME_Find);
check(TEST2 == NAME_None);
check(TEST2.IsNone());
Hi,
I have inspected the source code and made the following observations.
When an FName is constructed a check is done to determine if the FName contains a value to be used as an instance id. This check is performed by parsing the FName for a trailing underscore followed by any number of digits in the range 1-9. ( see function parseNumber in UnrealNames.cpp ). If so, this trailing string of digits is used as an internal number for comparison and uniqueness.
This could very well be by design to allow for manually providing an instance id to the FName, however it does seem to break the isNone function and equality operator and may also result in returning a false negative when doing comparison so I have sent off a bug ticket to Epic. You can monitor progress at this link when it becomes publicly available.
In the meantime if you did want to test for the existence of an FName instance you could use the following methods:
`check(FName(“None”, NAME_EXTERNAL_TO_INTERNAL(2)) == TEST2);
check(TEST2.GetComparisonIndex() == FNameEntryId::FromEName(EName::None));`or begin the trailing number sequence with the zero character. e.g.
FName TEST2(TEXT("ThisDoesNotExist_02"), FNAME_Find);
Kind Regards