Migrate code based blueprint?

hello

i have a blueprint based on custom code in 1 project and would like to migrate it to another project.
the blueprint took a long time to get how i want and im unable to reproduce it.
i have successfully copied the code over with a single change in the game api reference, but when i migrate the blueprint it says the base class does not exist.

is it possible at all?

thanks

It is possible. It involves a little work, though. From looking at the generated C++ from a 4.6 project, it looks like this may have changed for 4.6, but in 4.5 and earlier, the C++ classes have a project-specific Macro. For example, for one test project I have, it looks like this:



UCLASS()
class REPUBLICSNIPERAI_API AEnemyCharacter : public ABaseNPCCharacter
{
	GENERATED_UCLASS_BODY();


The REPUBLICSNIPERAI_API was auto-generated by UE4 based on the name of my project (RepublicSniperAI). In the project settings, it is defined as an empty string, so it has no effect on the generated code. I don’t know the full affect of this macro or how it’s used by UE4’s build system. With 4.6, it appears to no longer be used, but I’m not sure if something else takes its place.

So, to migrate the code, you copy the .h and .cpp files to your new project’s source folder, then you need to change this macro to the class-specific macro for your project. If the project you’re migrating to is a 4.6 project, it looks like you would simply remove the macro altogether, but maybe someone more familiar with the 4.6 engine changes can confirm that.

After that, there’s one more step you need to take. The blueprints that subclass or reference your migrated classes will have a reference based on the name of your old project. In order to deal with that, you need to put Active Class Redirects into your project’s* DefaultEngine.ini* file in your project’s Config folder. For each class that is used in Blueprints, you need to do something like this at the end of the DefaultEngine.ini file:



[/Script/Engine.Engine]
+ActiveClassRedirects=(OldClassName="EnemyCharacter",NewClassName="/Script/.EnemyCharacter")
+ActiveClassRedirects=(OldClassName="EnemyController",NewClassName="/Script/.EnemyController")
+ActiveClassRedirects=(OldClassName="BaseNPCCharacter",NewClassName="/Script/.BaseNPCCharacter")
+ActiveClassRedirects=(OldClassName="BaseNPCController",NewClassName="/Script/.BaseNPCController")
+ActiveClassRedirects=(OldClassName="FriendCharacter",NewClassName="/Script/.FriendCharacter")
+ActiveClassRedirects=(OldClassName="FriendController",NewClassName="/Script/.FriendController")
+ActiveClassRedirects=(OldClassName="NavigationMarker",NewClassName="/Script/.NavigationMarker")
+ActiveClassRedirects=(OldClassName="BTTask_MoveToward",NewClassName="/Script/.BTTask_MoveToward")
+ActiveClassRedirects=(OldClassName="BTTask_SelectRandomLocation",NewClassName="/Script/.BTTask_SelectRandomLocation")
+ActiveClassRedirects=(OldClassName="BTTask_StopMoving",NewClassName="/Script/.BTTask_StopMoving")
+ActiveClassRedirects=(OldClassName="BTDecorator_IsMoving",NewClassName="/Script/.BTDecorator_IsMoving")


[FONT=Courier New]OldClassName is the unmodified name of the C++ class without the prefix character (e.g. [FONT=Courier New]EnemyCharacter, not [FONT=Courier New]AEnemyCharacter). [FONT=Courier New]NewClassName takes the form [FONT=Courier New]/Script/ProjectName.classname.

Once you’ve done that, you should be able to migrate the blueprints from the editor to your new project the way you would any other blueprint.

Hope that helps.

that worked thanks :slight_smile:

You’re welcome. This was really hard to discover when I encountered it initially. I should probably take my answer and turn it into an Unreal Wiki posting.

it would be a great bit of info for the wiki, i would never have found that without you saying.
cheers

WOW it really works!
Does it work also for structures? I have a few and editor changed it to “unknow struct”
I tried +ActiveStructRedirects=(OldStructName=“sectorX”,NewStructName=“/Script/CleanThirdPerson.sectorX”) with no luck.

Hmm it has to be a way to redirect structs. I want to use Struct from migrated c++ actor inside migrated MyController.

This was so helpful! This method not so obvious because of “/Script/” part (answers in AnswerHub didn’t mention this).

I achieved some succes with autoreplacing in .uasset files but only with same string length, because of many many offsets that could be affected according to Asset file structure.

Now I can even rename project* or migrate code based Blueprints!

Worked in Engine Version 4.10.2

DefaultEngine.ini file:


[/Script/Engine.Engine]
+ActiveClassRedirects=(OldClassName="OldProjectName",NewClassName="/Script/NewProjectName")
+ActiveClassRedirects=(OldClassName="MyBlueprintBaseClass",NewClassName="/Script/NewProjectName.MyBlueprintBaseClass")
+ActiveClassRedirects=(OldClassName="MyEnumE",NewClassName="/Script/NewProjectName.MyEnumE")

Actually after recompiling and resaving all blueprints and maps these redirects can be removed!

*** - renaming project requires next steps:**

  1. Rename ProjectName.uproject (and Module name in it)
  2. Rename folder Source/ProjectName/
  3. Generate VS project files (project file context menu)
  4. Open generated VS solution file (with new project name)
  5. Autoreplace (Ctrl+H) in whole project ProjectName to NewProjectName (case sensitive!)
  6. Autoreplace (Ctrl+H) in whole project PROJECTNAME_API to NEWPROJECTNAME_API
  7. Rename ProjectName.Target.cs
  8. Rename ProjectNameEditor.Target.cs
  9. Rename ProjectName.Build.cs
  10. Rename ProjectName.[cpp,h]
  11. Probably you want to rename some files like ProjectNameGameMode.[cpp,h] if any present, but you should add right redirections for it (old class name to new one)
  12. Fix DefaultEngine.ini as above.
  13. Compile

First time there will be errors in message log, but if all dependencies are redirected, then blueprints can be opened, recompiled and resaved.

The class/enum/function/struct redirects were modified a bit, and the only docs I can find on it are in the 4.16 Upgrade Notes

When I migrated content from one code project to another, I used the new “MatchSubstring” feature in the new project’s DefaultEngine.ini:


[CoreRedirects]
+ClassRedirects=(MatchSubstring=True,OldName="/OldProjectName",NewName="/NewProjectName")
+EnumRedirects=(MatchSubstring=True,OldName="/OldProjectName",NewName="/NewProjectName")
+FunctionRedirects=(MatchSubstring=True,OldName="/OldProjectName",NewName="/NewProjectName")
+StructRedirects=(MatchSubstring=True,OldName="/OldProjectName",NewName="/NewProjectName")


When I opened the migrated maps/objects that used C++ classes that were copied over to the new project, the editor still gave me warning/errors, but a save quickly resolved the issue.

I was trying to copy an entire plugin’s content folder to a new plugin’s content folder, and this is the only method that worked for me.
I also had to add lines for:



+PackageRedirects=(MatchSubstring=True,OldName="/OldProjectName",NewName="/NewProjectName")
+PropertyRedirects=(MatchSubstring=True,OldName="/OldProjectName",NewName="/NewProjectName")
+ObjectRedirects=(MatchSubstring=True,OldName="/OldProjectName",NewName="/NewProjectName")


I just wanted to say thank you for this post, it saved me countless hours.

Hello!

I’m trying to migrate some BP classes from a project where parent classes are defined on the project source to a project where parent classes are defined in a plugin and I’m quite stuck, I have tried different *[CoreRedirects] *formats, with and without /Script/, but nothing:



[CoreRedirects]
+ClassRedirects=(OldName="/Script/OldProjectModuleName",NewName="/Script/NewPluginModuleName",MatchSubstring=True)
+PackageRedirects=(OldName="/Script/OldProjectModuleName",NewName="/Script/NewPluginModuleName",MatchSubstring=True)

also:



[CoreRedirects]
+ClassRedirects=(OldName="/Script/OldProjectModuleName.ClassName1",NewName="/Script/NewPluginModuleName.ClassName1")
+ClassRedirects=(OldName="/Script/OldProjectModuleName.ClassName2",NewName="/Script/NewPluginModuleName.ClassName2")


If you have any idea to point me in the right direction will be appreciated!

Thanks everyone. I had to add a couple of things to the solution to #9 to get it to work for me:
From



[CoreRedirects]

+ClassRedirects=(MatchSubstring=True,OldName="/OldProjectName",NewName="/NewProjectName")

+EnumRedirects=(MatchSubstring=True,OldName="/OldProjectName",NewName="/NewProjectName")

+FunctionRedirects=(MatchSubstring=True,OldName="/OldProjectName",NewName="/NewProjectName")

+StructRedirects=(MatchSubstring=True,OldName="/OldProjectName",NewName="/NewProjectName")


to




[CoreRedirects]

+ClassRedirects=(MatchSubstring=True,OldName="/Script/OldProjectName",NewName="/Script/NewProjectName")

+EnumRedirects=(MatchSubstring=True,OldName="/Script/OldProjectName",NewName="/Script/NewProjectName")

+FunctionRedirects=(MatchSubstring=True,OldName="/Script/OldProjectName",NewName="/Script/NewProjectName")

+StructRedirects=(MatchSubstring=True,OldName="/Script/OldProjectName",NewName="/Script/NewProjectName")

+PackageRedirects=(OldName="/Script/OldProjectName",NewName="/Script/NewProjectName")



just matching /OldProjectName would match and rename references to classes if class name contains OldProjectName, for example if you had a c++ class you were migrating named OldProjectNameGameMode, you would end up redirecting references to that class by blueprints that use it as a parent to NewProjectNameGameMode which you don’t want.

Also added PackageRedirects

If you check BaseEngine.ini in the UE4 build’s config folder there is helpful info there and you can see how they use these redirects with every new build of UE4.

In there it says

and then if you open the BaseEngine.ini and look at all the following lines you can see how they use core redirects for objects in the engine to provide compatibility with new engine releases.

1 Like

Thanks everyone,
In case someone was wondering, we have tested tomotor approach and it worked perfectly for Unreal 5 Early Access 2

1 Like