Editor Crash:: if (GetNumber() == NAME_NO_NUMBER_INTERNAL)

I set the break point to the function RandomItemID and on beginplay the breakpoint doesn’t hit, and the same crash error was happened.
I thought I need to start as debug editor to make the breakpoint work, this is why I changed it and now waiting for it to get compiled

on beginplay, this breakpoint was useless, the editor crashed on the old place line 3517
image_2022-08-18_045321520

Are you familiar with Step over/ Step into with breakpoints in VS?

yes, I am familiar with it, I use it always

waiting to complete it

image_2022-08-18_045932683

I’m still convinced it has to do with declaring FName with the same constructor in the same scope.

Could you try to modify your implementation to be this?
I’m assuming that the type of AmmoElemArray is a string? If it is you should convert them to const TChar array with * operator like I show below.

	case EItemType::E_Ammo:
		{
			if (const UDataTable* ItemAmmoRowNames = LoadObject<UDataTable>(GetWorld(), TEXT("/Game/DataTables/Items/Ammo/DT_ItemAmmo")))
			{
				for (auto& AmmoElemArray : ItemAmmoRowNames->GetRowNames())
				{
					if (const UDataTable* ItemAmmoFindRow{ LoadObject<UDataTable>(GetWorld(), TEXT("/Game/DataTables/Items/Ammo/DT_ItemAmmo")) })
					{
						if (const FST_ItemAmmo * OutRow_Ammo{ ItemAmmoFindRow->FindRow<FST_ItemAmmo>(*AmmoElemArray, "") })
						{
							if (OutRow_Ammo)
							{
								for (int32 i = 1; i <= OutRow_Ammo->ProbabilityPercent; i++)
								{
									TempTypeAndID_Setter.Type = EItemType::E_Ammo;
									TempTypeAndID_Setter.ID = *AmmoElemArray;
									Arr.Add(TempTypeAndID_Setter);//Adding elements

								}
							}
						}
					}
				}
			}
		}break;
1 Like

Of Course i will try it, just waiting for the engine to build, i am sure the engine want to build from scratch just for changing to Debug Editor :tired_face:

image_2022-08-18_091152503

Breakpoints shows this message
breakpoint can't be hit, no symbols are loaded for this document

*AmmoElemArray

The issue is this here. You are trying to dereference a reference to an FName, which is giving you a memory address not an FName value, essentially the FName is complete junk. This is a very good reason why we do not allow the use of auto or auto& unless the type involved has a very verbose name - it makes the code much more confusing for everyone, especially when you could have just typed FName.

There is no benefit passing around references to FNames, and this is never done in the engine source. FName is merely a pair of int32’s in non-editor builds, and passing it around by value is likely to be cheaper/faster/more convenient.

The above code is not particularly well written, so here’s a refactored version which is far faster and safer. You should never use LoadObject at runtime like this, the correct approach is to define a UDataTable* UPROPERTY and access it directly like so:

Header

// This meta will filter out tables which do not match the row type we want in editor
UPROPERTY(EditAnywhere, Category = "My Variables", meta = (RequiredAssetDataTags = "RowStructure=ST_ItemAmmo"))
const UDataTable* DataTableAsset;

Implementation

// Ensure the tables row-struct matches the row we want.
if (DataTableAsset && ensure(DataTableAsset->GetRowStruct() == FST_ItemAmmo::StaticStruct()))
{
	for (const TPair<FName, uint8*>& RowItem : DataTableAsset->GetRowMap())
	{
		// This is how data table internally accesses data
		const FST_ItemAmmo* MyRow = reinterpret_cast<const FST_ItemAmmo*>(RowItem.Value);
		for (int32 i = 1; i <= MyRow->ProbabilityPercent; i++)
		{
			// Do whatever
		}
	}
}

I have deliberately kept the int32 i = 1 here, but I am not sure that is correct. You probably want to start from the first element no?

Be aware that GetRowNames generates a complete COPY of the row names everytime you call it. It’s very inefficient to use it this way, and you can access the RowMap directly and reinterpret_cast to the correct type safely.

You could also make the data table reference a soft one, and load it sync/async at runtime.

3 Likes

I don’t Understand how I can get the row names by this method, I need to set them from the data table this is why I am looping the table to get all names and set.

in this image I show how I get/set the names, ....ID = FName(WeaponElemArray);

// this is taking names of each row.
FName(WeaponElemArray);
image_2022-08-18_135009187

RowItem.Key is the row name from my example above. It’s accessing the RowMap directly, the key is the row’s name, the value is the row’s data.

1 Like

Now it looks likes this and I am giving it a try, hopefully it will solve lots of problems

if a struct has multiple data tables, is it possible to access a specific data table by this method? or needs to load by URL?

auto is perfectly fine as long as the programmer knows what he is doing and the variables have good names. Looking at the number of threads and problems, I have the impression that the OP is a bit lost and his code looks like a blind shots.

1 Like

Sir i am not lost, but yes if i have a logic which is working in blueprint just fine and in C++ I need to overload the == operator for the type since the type is not mine, the type comes with the engine and it has no == operator

for(auto& Array_Elem_Transform : Array_Of_Transform )
{
    if(Array_Elem_Transform.find(row-of-transform) == -1)
    { 
       // Do Something
    }
}
Severity Error Code C2678 binary ‘==’: no operator found which takes a left-hand operand of type ‘const FTransform’ (or there is no acceptable Conversion

The time to get lost started at this point :smiley: because the == operator is available if you do this logic in blueprints. I think you are familiar with this, no?

There’s plenty of examples for operator overloading in C++ in the engine. You can look at FVector class for this.

1 Like

I looked at them and they will not help me, since I need to work with the world transforms of the meshes while spawning and later to work with Location, Rotation, Scale

currently this Solution helps me, but this is very expensive, sometime the engine just freez on beginplay

by the help of @Rumzie @gh0stfase1 @Jambax this quesiton is solved. Thank you Guys very very much helping me in my studies of Unreal C++ :slightly_smiling_face:

coming to the problem we were trying to solve, the main root of the problem was this assignment of array range (0 ,99) it was always nulled because the data table was corrupted which I am loading by URL, and created the new data table and assigned, now the array update its range according to the row count in the data table and this RandRange is randomizing the range correctly. Function RandomItemType();

2 Likes


I think the issue is fully solved, here I am just not printing the correct values of item types and probability numbers