With the UE5.5 update, a number of properties were moved into a system called Sparse Data. By design this system acts like static member properties and was designed to be read-only.
We have modified the sparse data system to make most of these properties writable, but it is important to understand that they are still static, meaning that changing the value on one instance of a given class changes the value for ALL instances of a given class.
Uses of Sparse Data properties will be annotated with the "-CLASS GLOBAL-" as shown here. there will also be notes shown in the compiler window of the blueprint and in the log window
(Please note that right now these annotations will only be shown if the node is actually connected to something on the execution chain and then compiled)
In addition to supporting writing to the sparse data properties directly we have also implemented support for instance overrides of the sparse data properties.
Right now only a few properties are supported, but we will add more over time.
When a property supports instance overrides the bp compiler will provide the following warning when using thhe direct setter.
Using a direct setter on a Sparse Data Property that has instance override support, this will set the value for ALL instances of this class. Consider using a SparseDataOverrideManagerClass instead!
This signifies that we have implemented instance overrides for that property, and while you can continue to use the direct setter that affects all instances, you might want to consider using instance overrides instead.
To start implementing instance overrides, create a new blueprint in your mod that is a child of SparseDataOverrideManager and then link that to "Sparse Data Override Manager" in either the worldsettings of your map if you have a map mod, or in the primalgamedata of your mod.
NOTE: the override manager can be linked in the mod data asset but there is currently a bug with linking it there that will cause mods to fight each other for which one gets instantiated, use the PrimalGameData link for now until the fix goes out in a build
To actually use this class, simply click on the "override" list in the functions panel. You will see a list of all supported properties. As this list grows it may become rather difficult to find the override you want if you don't use the search bar. All overrides will include the exact name of the property.
When you first open your new override manager it will be very empty. There is currently only one default property to set and that is for Manager ID.
Pick your own ID, make it something unique, this is sort of like a passkey for finding your own override manager instance when you want to pass data to it.
Don't forget to set a manager ID or you will have trouble finding your manager while the game is running using the GetSparseDataOverrideManager function.
This is how you can pass any data you need to your override manager (add your own properties, functions, maps, etc) in order to manage how you handle these overrides.
if the data you need in order to determine your return value is part of the instance you are modifying, just cast the "ForInstance" reference to the appropriate class.
All the overrides will follow the same structure of signature:
Base Value: This is the actual value that is set to the sparse data property.
Current Value: This system is stackable, meaning other mods can also overrides the values. This allows you to see what the current value currently is at to see the difference against the Base Value.
For Instance: This is a reference to the instance the override is being called for, you will have to cast this yourself.
Return Value: This is the value that will be returned for this specific Get call. Every override manager will have an opportunity to modify the value before it is actually returned to the original Get call.
IMPORTANT NOTE: Because instance overrides are called for every "get" in both native and blueprint. you must NEVER use the GET for that property from within the instance override function. you will create an infinite loop. This is why the "Base Value" input in the override is provided, so that you have access to that value without creating a recursive loop
It is important to understand that some of these properties may be getting accessed frequently so it is a bad idea to put any heavy operations in the override functions. Instead consider mapping your modifiers in the override manager and doing any heavy operations outside of the instance override function itself, then caching them for use when the override is called.
And that's it.
Instance Overridable properties do not need to have their get uses replaced with any functions, the instance override support refactoring is done automatically at cook time of your mod files.
More sparse data properties will be added to this over time.