How to not lose code when renaming functions in a C++ interface

The problem

By default, with Rider on UE 5.1, renaming a C++ interface function could make you lose everything you implemented in blueprint for these functions.

For instance, here is aninterface with two functions InterfaceEvent and InterfaceFunction:

class EMPTYMODULE_API IInterfaceName
{
	GENERATED_BODY()

public:

	UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
	void InterfaceEvent();

	UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
	bool InterfaceFunction() const;
};

And here is a blueprint implementation:


image

If I rename InterfaceEvent to InterfaceEventNewName and InterfaceFunction to InterfaceFunctionNewName, you loose your code, even if you enable RIder’s option to create CoreRedirect entries:

image

The event is not an implementation of the interface anymore, and what I put in InterfaceFunction was just lost :man_shrugging:

Imagine losing all your implementations over multiple blueprints…


The solution

Rider will add these two entries in [CoreRedirects] when renaming the function:

+FunctionRedirects=(OldName="/Script/EmptyModule.IInterfaceName.InterfaceEvent",NewName="/Script/EmptyModule.IInterfaceName.InterfaceEventNewName")
+FunctionRedirects=(OldName="/Script/EmptyModule.IInterfaceName.InterfaceFunction",NewName="/Script/EmptyModule.IInterfaceName.InterfaceFunctionNewName")

Simply remove the I prefix on the interface name:

+FunctionRedirects=(OldName="/Script/EmptyModule.InterfaceName.InterfaceEvent",NewName="/Script/EmptyModule.InterfaceName.InterfaceEventNewName")
+FunctionRedirects=(OldName="/Script/EmptyModule.InterfaceName.InterfaceFunction",NewName="/Script/EmptyModule.InterfaceName.InterfaceFunctionNewName")

And now when you open your blueprints it should work! :sparkles:

image

:bulb:Once you are done refactoring, you can open all the depending blueprints and re-compile and save them to force them to use the name function names and don’t depend on core redirects anymore.


Thanks @FunGames55 for the explanations on CoreRedirects.

1 Like

Yes, I’ve run into this with interfaces as well. It’s a bit inconsistent of when you drop the prefixes and when you don’t as structs keep the “F” prefix for instance and enums keep “E”, though these are StructRedirects and EnumRedirects respectively. UClass macro names look to all drop prefixes like “A” and “U” from what I’ve experienced for ClassRedirects. Figured this out by searching the engine code for examples. Another thing as you evolve the codebase is you can have at most 1 redirector for a given old class name. It’s not so much an issue if you rename since the name will be different, but if you move classes to new modules multiple times you only keep the latest “NewName”. The convention is to not have a module prefix for “OldName” and only be specific for “NewName” which is required. Then you can just update the redirectors in place with a new module location in “NewName”:

+ClassRedirects=(OldName="MyClass",NewName="/Script/MyNewModule.MyClass")