Is there a way to assign a tag to a Uproperty?

I want to assign a number to each property in a uobject. the number needs to be accessible at runtime.

I know the uproperty name is accesible at runtime, so i could append my number to all uproperty names, and split the property name string to read the number. however this would be a rather ugly way to do it.

No, there is no way to add a tag to the property.

It sounds to me as if there’s a better way to accomplish what you want, though. Maybe you want a property that’s an array-of-numbers? Or a property that’s an array-of-structs, where each struct has a few properties in turn? Or a fancier container, like a map?

I could define a map of property names to number like so:

static TMap<FString, uint8> PropOpCodeNames = {
{“apropertyName”, 0},
{“anotherPropertyName”, 1},
{“AndAnother”, 2}
};

However this could become hard to manage. Is there possibly a way to compile this map of numbers and property names from Uproperty metadata, so it can be used at runtime?

I still don’t understand what your use case is.
What are the numbers needed for?
Where does the data come from in the first place, and what do those data represent?
It feels a lot like you’re trying to solve some particular problem with some particular approach where it’s very likely a better solution already exists using some other approach, but recommending where to look is impossible if I don’t know what you’re actually trying to accomplish.

Besides what @jwatte said, you should be able to add any arbitrary metadata that you like whenever it’s allowed to write meta = (...) and retrieve it later. For example from the FProperty via GetIntMetaData. There are few more metadata related functions in UField.

Note that metadata only exists in editor not at runtime of the game

This is my use case:
I want to save and read UObjects to files on disk. However I only want to save certain properties, not all of them. I do not want to encode/decode variables in a fixed order, because the encoding/decoding formats will change in the future.

So my plan was to assign a byte to each variable, and use a switch statement to read and write the variable linked to that byte to/from the file on disk.

The SaveGame system already solves this problem. Can you use that? You can set the “not part of savegame” flag on properties.

Another option is to save the name of the property, rather than a number. This will be more robust, and additionally will work well if you decide to send these data as JSON or XML for some reason (like, web services or what not.)

A third option is to make a Map of the names of properties to save and their “ID” for each class, and look up each property in this map. Set up this map in the “class defaults” and then don’t edit it on object instances (make it not instance editable) and all instances of the same class will use the same map.
Define an interface ISaveable that returns this map for each kind of object you want to be able to save.

Thanks for the suggestions, each of method has its own advantages.

A Map of names to id’s seems the best method so far, at least as the base. Its just a bit of a pain to manage.

These are the requirements i had in my head:
Need to manually define the data length of each property.
Need to manually define whether the property is savable.
Need to read/write properties very fast.
need to be able to rename properties
file encoder format must be flexible/changeable.

The file data will be used to store large amounts of data such as terrain/entire maps, and streamed over internet and decoded fast. For that reason save-games are not great.

If that is the requirement, then it’s probably better to define the file format in terms of binary structures, and have a method on your objects to “inhale this structure” and “exhale this structure,” which lets you fully de-couple properties from the file format. You do need to write those two functions, but they are then the clear interface, and give you full freedom for the file and network serialization.

Trying to look up properties one by one is unlikely to work well if you actually have a goal of high performance – whether you do it by map, name, or number, doesn’t matter; the fact that you do any kind of lookup per property is the high-order bit here.

Personally, when I do these inhale/exhale things, I end up writing a simple visitor template, something like:

template<typename T> void UMyObject::visit(T st) {
  visit(st.someInt, MyIntProp);
  visit(st.someString, MyStringProp);
  visit(st.someFloat, MyFloatProp);
  visit(st.someOtherFloat, MyOtherFloatProp);
}

void UMyObject::Inhale(FileStruct const &src) {
  visit(src);
  AfterPropsChanged();
}

void UMyObject::Exhale(FileStruct &dst) {
  BeforePropsSave();
  visit(dst);
}

And then define appropriate visit() function specializations for updating whatever your member types and widgets are – they’re typically reusable.
You will then have one step that is the “file format handler” that knows how to read/write your file format, using the defined structs, and then use those structs as the interface to your Unreal actors. This de-couples the I/O and lets you be as efficient as you need.

Also, that “file format structs” library could conceivably be used outside of Unreal, too, should that ever be needed.