Community Tutorial: Updating Action RPG from UE4 to UE5

This step-by-step procedure shows how to proper update the code of your Action RPG project to UE5.

https://dev.epicgames.com/community/learning/tutorials/d8Ra/unreal-engine-updating-action-rpg-from-ue4-to-ue5

5 Likes

Awesome, on my To-do list for tomorrow. Thanks mate.

1 Like

Can you please upload the files that are changed somewhere for people to download?

hi, I didn’t plan to create a repository of files for this update, because there are only 5 lines of code to change. I am trying to update Vehicle Game to UE 5.1, in this case, and if I succeed, I’ll see if I can setup a GitHub account for it.

2 Likes

I do get just error with part:

3.1 RPG_TargetType.cpp:

Line 26

Changes from: OutActors.Add(const_cast(EventData.Target));

To: OutActors.Add(const_cast(ToRawPtr(EventData.Target)));

Error message:

1>RPGTargetType.cpp(26): error C2760: syntax error: '(' was unexpected here; expected '<'
1>RPGTargetType.cpp(26): error C2059: syntax error: '('

Still thank you for helping out.

Hi there,
Thank you for bringing me this error to my attention. The <AActor*> was missing in my text. The correct lines are:

From: OutActors.Add(const_cast<AActor*>(EventData.Target));
To: OutActors.Add(const_cast<AActor*>(ToRawPtr(EventData.Target)));

This is what I have:
image

Give it another try and let me know. I’ll update the tutorial.

Edit: As an update, the reason for this error is that, when copying and pasting the text into the tutorial editor, the “<AActor*>” gets supressed, perhaps because of the symbols. I didn’t notice this. Thank you again for letting me know.
Good luck in your project.

1 Like

Thank you. It works now like a charm :wink:

1 Like

Does your windows taskbar icon work when doing this?

Thank you man! You save the day!
Success and strength to you!

1 Like

Glad it helped. Keep up the good work.

Edit Note, Ooops, I see now you only tested for 4.27 to 5.0 to 5.1 and not 4.27 to 5.1! I have edited the post to reflect this realization. I assumes this does mean you need to have Engines 5.0 to update to 5.1 or do I also need 4.27 as well?

Can you also clarify the following steps?:

“1. Create a new project and open it up.” This refers to the Action RPG sample project correct? Not a blank project of some other kind?

Additionally which way should I open it up? Double clicking the uproject file, opening it via the Unreal Engine 5.1 launcher under “Browse”, or by Generating Project files (Using 5.1?) and then compiling in VS? (I am using 2019 VS to be clear)

“2. Disable MDL and Slate Remote plugins”

I saw that you could disable Slate Remote by editing the uproject file, but I don’t seem to see which Plugin MDL refers to, do you have a screenshot?

Another edit:
Regarding the suggested change here:

Changes from: check(AbilitySystemComponent);

To: UAbilitySystemComponent* ASC = GetTargetASC();

    if (ASC)

Is this meant to be:

UAbilitySystemComponent* ASC = GetTargetASC();

if (ASC != nullptr) {
    OnAbilityCancelled();
}

Correct?

One last question for the following:

Line 11:

No changes, just "Cut and paste":  Super(ObjectInitializer)

I’m just a little confused, is this saying if “Super(ObjectInitializer)” wasn’t present then we should add it? Otherwise do nothing right?

Edit with Results:
Upgrading straight to 5.1 Seems to work just fine.

There was some initial weirdness with trying to open the project, the way I would re-phrase the steps to be slightly clearer is…

Steps to go from 4.27 to 5.1:

  1. Create a new ActionRPG Project in the Unreal Engine launcher.
  2. Edit the ActionRPG.uproject file and scroll down to “SlateRemote” and change it from “true” to “false” without quotes.
  3. Generate Project files using 5.1
  4. Open the ActionRPG.sln in your IDE of choice, presumably Visual Studio 2019 or 2022.
  5. Follow the suggested code changes as per your original article, although I would clarify that the line 180 suggestion regarding check(AbilitySystemComponent); probably is meant to have OnAbilityCancelled(); in the added if statement?

And that seems to work.

There is an addendum to make though that maybe I would add the following step:
6. Go to Project Settings and to Supported Platforms and re-check if they are correct for your use, such as adding Windows and removing the others if you just intend to Package for Windows.

1 Like

Hi there,
I appreciated you taking the time to review my procedure. To your question, you can go from 4.27 directly to 5.1. I gave it a try and it worked correctly. Also, you can use any IDE of your choice. However, I tested only with VS 2022. Even If you don’t have 4.27 installed, you can create a new Action RPG project, then convert it to 5.1, generate project files, and edit the project with your IDE without opening the project in editor, disable Slate Remote and MDL plugins in your project file. It may work correctly, but I haven’t tested this way. I created a 4.27 project, opened in editor, disabled the plugins, closed the project, converted to 5.1, then went to VS 2022.

Your suggested change is not what I meant, at least I haven’t found any undesired results after converting the project. Let me know if you suggestion works for the case you have to cancel an ability.

Regarding disabling both Slate Remote and MDL: MDL plugin still exists in 5.1, and back in day I wrote this procedure, not disabling it from 4.27 project caused infinite cooking time in 5.0. Slate Remote changed to Slate Insights in 5.0.

Line 11 Super(ObjectInitializer): more than likely was a unusual VS error that always persisted and prevented the correct compilation until cutting and pasting the line.

Good luck in your project.

@L.F.A thanks for getting back to me! Your response certainly clarifies things for me. Although to be clear my intention in upgrading the project is to learn how it does the pre-loading screen. :slight_smile:

Regarding MDL here is what the ActionRPG uproject file looks like for me:

Assuming by MDL you mean MDLImporter as I think I’ve seen it called, I don’t see it in the list? Is it under a different name then what I assumed?

Okay I am confused, what does if (ASC) do in your code? It’s a conditional right, so if ASC is null/invalid what should occur? What does the function look like in your code may I ask? For me it looks like this:

void URPGAbilityTask_PlayMontageAndWaitForEvent::ExternalCancel()
{
	UAbilitySystemComponent* ASC = GetTargetASC();
	if (ASC != nullptr)
	{
		OnAbilityCancelled();
	}

	Super::ExternalCancel();
}

For you does it look like this?:

void URPGAbilityTask_PlayMontageAndWaitForEvent::ExternalCancel()
{
	UAbilitySystemComponent* ASC = GetTargetASC();
	if (ASC)
        OnAbilityCancelled();

	Super::ExternalCancel();
}

Isn’t this the same?

Before IIRC it was like this:

void URPGAbilityTask_PlayMontageAndWaitForEvent::ExternalCancel()
{
	check(AbilitySystemComponent);

	OnAbilityCancelled();

	Super::ExternalCancel();
}

check(…) IIRC is about throwing an exception if the passed in object isn’t valid, since your suggestion is to change it to an if, presumably we’re still checking if ASC is valid and then not doing something right? Otherwise why bother if we’re not passing ASC as a variable? Because if (ASC) isn’t like check(AbilitySystemComponent) and won’t throw an exception I am pretty sure, so now I’m a little puzzled behind the intent of the change.

You may want to check the name as it appears in 4.27 editor.

ASC is a local variable, it could be renamed whatever you wanted. That’s how Lyra’s reference to Ability System Component was updated from 5.03 to 5.1.

That’s how Lyra’s code was updated from 5.03 to 5.1.

To be clear, I am pointing out that at a glance it looks like the change to the ExternalCancel() function doesn’t make a lot of sense in context; which is why I am asking clarification questions to know if there is a deeper meaning, intention or context I am not aware of looking at the code at a glance.

By your earlier post the point of the if (ASC) isn’t meant to shadow the OnAbilityCancelled(); function call; so the if-statement doesn’t seem like it’s doing what’s intended in that function and probably should be removed/omitted entirely or changed back to check(…).

Because to be clear it absolutely is in fact shadowing OnAbilityCancelled(); An if-statement without brackets just means the next statement is what’s in the if’s scope; which is OnAbilityCancelled();.

Because an if-statement isn’t the same thing as check(), check throws an exception afaik if the object pointer being passed in is null. So if the goal is to make sure the pointer isn’t null and throw an exception if so then it should stay as check(…).

Do you understand what I’m saying? I isn’t really important “what” the change was at this moment, the problem is that this particular suggested change in the upgrade to 5.1 doesn’t make a lot of sense or match the original intent; unless I’m wrong and there is a deeper intent I am missing.

If I’m not wrong then the guide I’d suggest you edit to reflect the suggested change for clarity.

Hi there, I understand what you’re saying, and I am Okay with it. What you’re saying makes sense, however, have you noticed in the original code section (line 178) doesn’t include brackets in the if statement? Either it might be overlooked by the devs, or is not a problem at all.

Further, I got that way of referencing Ability System Component by comparing both 5.03 and 5.1 of Lyra Starter Game (AbilityTask_WaitGameplayEvent.h and AbilityTask_WaitGameplayEvent.cpp). Who knows, I might have missed something.

Let me see if I find my notes archived, because I am traveling without my working computer. Unfortunately, I won’t be able to review this code any time soon. Have you tested your suggested code in a packed game yet? I’ve built three working prototypes and haven’t found any errors. All abilities were executed just right. Let me know if you find any warnings or errors.

Hello! Thank you for replying, I believe we can narrow down the source of our misunderstanding now. :slight_smile:

So in the original UE 4.27 source code there is no if-statement.

As you can see here.

In case the image doesn’t load here I’ll quote the original code before the upgrade to UE 5.1:

void URPGAbilityTask_PlayMontageAndWaitForEvent::ExternalCancel()
{
	check(AbilitySystemComponent);

	OnAbilityCancelled();

	Super::ExternalCancel();
}

As you can see there’s no if-statement.

And for reference this is how the instructions look to me on the website:

ActionRPG Upgrade

And I didn’t get the sense when I asked my question that what you meant was:

	UAbilitySystemComponent* ASC = GetTargetASC();
	if (ASC)
		OnAbilityCancelled();

Which would’ve been fine, but I think you said this isn’t it?

As for whether I test it yet, not yet as the main thing I was aiming for from the ActionRPG project was the Preloading Screen as it is literally the only tutorial resource for how to have a pre-loading screen instead of a black application window. But I think we can clearly see as long as the ASC exists then there is no change in behaviour. The question was, “What should happen if the ASC doesn’t exist?” and what this intent was wasn’t clear with the upgrade to 5.1.

I assume the Lyra Starter Game is a different game template project? If they happened to have the exact same code without brackets and without a statement clearly on the next line and indented then the only thing I can speculate is that they made a mistake.

Like its fine to have:

if (bFrogsAreCool)
    print("Yeah Frogs are Cool");

It’s a legitimate style, what is not fine I feel is:

if (bFrogsAreNotCool)



print("I hate frogs >:(");

Because the print statement in the second example is still going to be enclosed in the scope of the if, but it isn’t clear to anyone reviewing the code; which is what the update instructions for the ActionRPG project seem to imply should be the change?

I hope this clears up the discussion and resolves the misunderstanding I think we were having, I hope you’re travelling safely. :slight_smile:

1 Like

Hi there, glad to know we are good. Yes, the original code has no if statement, however, the only way Visual Studio would allow me to build my 5.1 solution was replacing the “check(AbilitySystemComponent);” by something else not clear to me back in the day. Because I didn’t receive any feedback from the community, I decided to use Lyra’s latest reference: “UAbilitySystemComponent* ASC = GetTargetASC();
if (ASC)”,

That was the only way to build my solution without errors. But, as you pointed well, perhaps the final “if(ASC);” is either unfinished or even unnecessary. So, once I return to my project, I’ll try both codes and see if I can find any errors while cancelling an ability by external event. Typically, this node is triggered when one gameplay effect has a tag that cancels an active ability, or when player triggers the cancel input. One of my prototypes has an ability cancellation by input (grenade), and I haven’t had any problem so far.

If ASC doesn’t exist, more than likely, either player or NPC has died while waiting for valid target data (e.g. Aiming) and all active abilities will be cancelled. The only way to know is via debugging the delegate “OnAbilityCancelled()” and see where it leads to. Typically, it will send an event to the listening node “Wait Target Data”, resulting in an active ability that is listening for external cancellation events being cancelled. Keep in mind that “URPGAbilityTask_PlayMontageAndWaitForEvent” is a custom task created as a learning example for that game, extended from “UAbilityTask_PlayMontageAndWait”. Therefore, another way to debug this code is by comparing both objects.

Also, Action RPG was created as a learning source, and it is very likely that a few parts of the code were left unfinished because we had UE5, and Lyra came to replace it. Lyra is multiplayer-ready and has way more advanced Gameplay Ability System than Action RPG.

I’ll update here if I find anything. Keep up the good and good luck with your project.

I have yet to be able to accomplish this, would anyone be willing to share their project?