UE4: Deprecating Symbols
~ 3 Minute Read.
I find myself googling for how to deprecate UENUM, USTRUCT, UCLASS, UPROPERTY, UFUNCTION in Unreal Engine 4 every now and then. With this blog post I hope to provide a reference for how to do this for each:
UPROPERTY
These are a matter of simply appending _DEPRECATED to their name and removing all metadata attributes. This will allow blueprints to still compile. I recommend removing all uses of the deprecated property during rename instead of just refactoring the name of the symbol.
Additionally, specify DeprecatedProperty and DeprecationMessage in the UPROPERTY() macro for some addition information to the user.
// Before
/** Number of elements */
UPROPERTY(EditAnywhere)
int32 Count;
// After
/** Number of elements
* @deprecated Use Size instead
*/
UPROPERTY(meta=(DeprecatedProperty, DeprecationMessage="Use Size instead."))
int32 Count_DEPRECATED;
UFUNCTION
Here you only need to be adding the meta specifiers. You do not need to remove the other specifiers here nor rename the function.
// Before
/** @brief Get answer to everything */
UPROPERTY(BlueprintPure)
int GetAnswerToEverything() const {
return 42;
}
// After
/** @brief Get answer to everything
* @deprecated Use GetEarth() and GetAnswer() instead.
*/
UPROPERTY(BlueprintPure, meta=(DeprecatedFunction,
DeprecationMessage="Use GetEarth() and GetAnswer() instead."))
int GetAnswerToEverything() const {
return 42;
}
UCLASS
These have a special Deprecated specifier that you should use to mark the class. Additionally, you will need to rename it:
// Before
UCLASS()
class UMyObject : public UObject {
GENERATED_BODY()
/* ... */
};
// After
UCLASS(Deprecated)
class UDEPRECATED_MyObject : public UObject {
GENERATED_BODY()
/* ... */
};
UENUM
These don’t seem to have graceful means for being deprecated. In the engine’s code you can find enum values that are deprecated by suffixing them with _DEPRECATED. That is not necessarily “graceful” on its own, as in it isn’t picked up by the blueprint system and will cause compile errors there.
// Before
UENUM()
enum class EMyEnum : uint32 {
MyValue = 0,
YourValue = 1,
/* ... */
};
// After
/* @deprecated This was removed in version XY */
UENUM()
enum class EMyEnum_DEPRECATED : uint32 {
/* @deprecated This was removed in version XY */
MyValue_DEPRECATED = 0,
/* @deprecated This was removed in version XY */
YourValue_DEPRECATED = 1,
/* ... */
};
To ensure blueprints keep compiling, you can add redirects, e.g. in your DefaultEngine.ini:
+EnumRedirects=(OldName="/Script/MyGame.EMyEnum",
NewName="/Script/MyGame.EMyEnum_DEPRECATED",
ValueChanges=(("MyValue","MyValue_DEPRECATED"), ("YourValue","YourValue_DEPRECATED")))
While blueprints will not issue a warning, the user will at least see that _DEPRECATED suffix, hopefully hover over something that shows the code comments in a tooltip and make necessary changes.
See Unreal Engine Documentation > Programming Guide > Core Redirects for more information on redirects.
USTRUCT
These don’t seem to have graceful means of deprecation either. I suggest to either deprecate the C++ side gracefully (see Non-Blueprint Types) and then deprecate all the attributes:
// Before
USTRUCT()
struct FMyStruct {
GENERATED_BODY()
/* ... */
UPROPERTY()
FString Name;
};
// After
USTRUCT()
struct DEPRECATED(4.20, "MyStruct is deprecated, use YourStruct instead.") FMyStruct {
GENERATED_BODY()
/* ... */
UPROPERTY(meta=(Deprecated,
DeprecationMessage="MyStruct is deprecated, use YourStruct instead."))
FString Name_DEPRECATED;
};
… or do something similar to the rename and redirect analog to how you would for UENUM.
See Unreal Engine Documentation > Programming Guide > Core Redirects for more information on redirects.
Non-Blueprint Types
If you maintain a plugin that provides a C++ only API (maybe in addition to Blueprint nodes), you can deprecate such symbols using the DEPRECATED(version, message) macro:
// Before
virtual void foo();
// After
DEPRECATED(4.20, "Use bar() instead.")
virtual void foo();
Written in 70 minutes, edited in 6 minutes.