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.