4.25 Transition Guide

Dear Community,

4.25 is here! Wohoo!

Please post your questions about the upgrade to 4.25 here, and also any compile errors you resolve on your own so that others may benefit.

Thank You Epic for 4.25!

:heart:

Rama


Reminder: If you are unable to compile after edits to your project or plugin C++ code:

**"Command line is too long to fit in debug record"**

[https://developercommunity.visualstu...happening.html](https://developercommunity.visualstudio.com/content/problem/668411/command-line-error-d8049-still-happening.html)

Simply add this line to the build.cs:



```


bLegacyPublicIncludePaths = false;


```



UObjectProperty Becomes FObjectProperty

(BrUnO XaVIeR explains more below!)



UObjectProperty* ObjProp = Cast<UObjectProperty>(Property);


becomes



FObjectProperty* ObjProp = CastField<FObjectProperty>(Property);



Happy Coding!

♥

Rama
2 Likes

UProperty and all subclasses are not UObjects anymore…

A weak pointer went from


TWeakObjectPtr<UProperty> myProperty;

to


TWeakFieldPtr<FProperty> myProperty;

[HR][/HR]You can still use


FProperty::StaticClass();

and


myProperty->IsA( FxxxProperty::StaticClass() )

[HR][/HR]You can’t use anymore


myProperty->GetOuter();

you have to use instead


myProperty->GetOwner<UObject>();

[HR][/HR]You can’t use Cast<> on FProperties like before


CastChecked<UStructProperty>(myProperty);

Now you have to use a different one:


CastFieldChecked<FStructProperty>(myProperty);

FImageWriteTask now accepts TArray64 as data instead of a TArray. If you have a regular TArray, pass it in like this:


TArray<FColor> OutBMP;
// Fill OutBMP somehow
TUniquePtr<TImagePixelData<FColor>> PixelData = MakeUnique<TImagePixelData<FColor>>(DestSize);
PixelData->Pixels = OutBMP;
ImageTask->PixelData = MoveTemp(PixelData);

[HR][/HR]2)
Shaders no longer have an explicit


virtual bool Serialize(FArchive& Ar) override

method to serialize.

This is now instead achieved by wrapping all shader parameters in a LAYOUT_FIELD macro.



FShaderResourceParameter ReadBuffer // Old declaration
LAYOUT_FIELD(FShaderResourceParameter, ReadBuffer); // New declaration


For the LAYOUT_FIELD macro to work, the shader needs to be declared with the DECLARE_SHADER_TYPE macro (which most shaders probably have, see side note below). [HR][/HR]2b)
Side note for people using inheritance with shaders (probably not a huge subset of people) :

Using the normal macros for shader declare/implement breaks inheritance with virtual functions in shaders.
Got this to work - if you have a shader that’s intended only as a parent shader (not to be implemented) with virtual methods, you have to call


  DECLARE_EXPORTED_TYPE_LAYOUT(FYourShaderName, YOUR_API, Virtual);


within the shader declaration and in a .cpp somewhere do


IMPLEMENT_UNREGISTERED_TEMPLATE_TYPE_LAYOUT(, FYourShaderName);


And in shaders with virtual methods (where the shader will be implemented), you have to call



  INTERNAL_DECLARE_SHADER_TYPE_COMMON(FYourSecondShaderName, Global, YOUR_API);
  DECLARE_EXPORTED_TYPE_LAYOUT(FYourSecondShaderName, YOUR_API, Virtual);


in the class declaration and standard IMPLEMENT_GLOBAL_SHADER in a cpp somewhere.

With this setup, it seems the serialization of shaders works fine with virtual methods too.
Not sure why Epic decided that you won’t ever need a virtual memory layout with shaders (their regular macros assume it, see DECLARE_EXPORTED_SHADER_TYPE). [HR][/HR]

2 Likes

Tried 3 computers, 3 fresh installations, 2 different migrated projects and 3 new projects on each pc with steam open and I cannot get steam subsystem to load, no overlay etc. think its broken

i did check i had steam > in game overlays turned on. was there any changes/new parameters that need changed to get it to work again?

this is tied to forum post UE4 4.25 Steam Issue - C++ Gameplay Programming - Unreal Engine Forums

Any idea for macros like “GETSAFERHISHADER_VERTEX”? They were completely removed.

Thanks! This is super helpful. Also it seems that the old helper functions like GetComputeShader() are gone from FShader. Do you have any insights on how to migrate from there?

It’s been just changed a little bit. This works:



  TShaderMapRef<FYourShaderName> ComputeShader(GetGlobalShaderMap(ERHIFeatureLevel::SM5));
  FRHIComputeShader* pShaderRHI = ComputeShader.GetComputeShader();
  RHICmdList.SetComputeShader(pShaderRHI);


Those I haven’t been using, try lurking through commits to the file where they were defined on Epic github. It’s always an adventure with a new version :smiley:

OK. So like we can no longer call GetComputeShader() from inside custom shader now? Cause I used to do things like



class FMyShader : public FGlobalShader
{
...
    void BindShaderBuffer(FRHICommandList& RHICmdList, FUnorderedAccessViewRHIRef OutputBufferUAV)
    {
        SetUAVParameter(RHICmdList, GetComputeShader(), OutputBuffer, OutputBufferUAV);
    }
}

Use this:


RHICmdList.GetBoundComputeShader();

For me, it says GetComputerShader is not a member of my class. It means DECLARE_SHADER_TYPE and IMPLEMENT_SHADER_TYPE does not work correctly anymore?

I confirm that the code tommybazar posted does work. Note that it’s not dereferencing from ComputeShader, it’s actually accessing the member function GetComputeShader of TShaderMapRef. So instead of the old ComputeShader->GetComputeShader(), it’s now ComputeShader.GetComputeShader();

If you were using


UProperty*

for wildcard property passing in Blueprint, the transition that worked for me was


TFieldPath<FProperty>

e.g.


UFUNCTION(BlueprintCallable, CustomThunk, meta = (CustomStructureParam = "AnyStruct"))
static bool ReadAnyStruct(TFieldPath<FProperty> AnyStruct);


Also in my case, stepping through a custom thunk,


ExactCast 

became


CastField

e.g.


FStructProperty* StructProp = CastField<FStructProperty>(Stack.MostRecentProperty);

In case someone runs into this problem,
**FImageWrapperBase **now uses **MoveTemp **for its GetRaw, which means that you can’t use an **rvalue **for the RawData, and the overridden **GetRaw **for **IImageWrapper **was changed to use a TArray64.

Example of the change:


TArray<uint8> *RawDataPtr = NULL;
TArray<uint8>& RawData = *RawDataPtr;
if (ImageWrapper->GetRaw(ERGBFormat::RGBA, 8, RawData))

Should be changed to:


TArray64<uint8> *RawData;
if (ImageWrapper->GetRaw(ERGBFormat::RGBA, 8, RawData))

I ran into this issue because I was using ImageWrapper for a UTexture2DDynamic.

Any ideas how to fix this kind of error:


Assertion failed: !Obj->HasAnyFlags(RF_NeedLoad) [File:D:/Build/++UE4+Licensee/Sync/Engine/Source/Runtime/Engine/Private/Animation/AnimCompressionTypes.cpp] [Line: 403] Failed to load AnimBoneCompressionSettings /Engine/Animation/DefaultAnimBoneCompressionSettings.DefaultAnimBoneCompressionSettings in AnimSequence /Game/Run/Animations/Movement/Idle.Idle


AnimCompressionTypes.cpp at 403 https://github.com/EpicGames/UnrealE…ssionTypes.cpp


 [TABLE]

template void FUECompressedAnimData::ByteSwapData(TArrayView<uint8> CompressedData, FMemoryReader& MemoryStream);
 		

 
 			template void FUECompressedAnimData::ByteSwapData(TArrayView<uint8> CompressedData, FMemoryWriter& MemoryStream);
 		

 
 			 
 		

 
 			void ValidateUObjectLoaded(UObject* Obj, UObject* Source)
 		

 
 			{
 		

 
 			#if WITH_EDITOR
 		

 
 			if (FLinkerLoad* ObjLinker = Obj->GetLinker())
 		

 
 			{
 		

 
 			ObjLinker->Preload(Obj);
 		

 
 			}
 		

 
 			#endif
 		

 
 			checkf(!Obj->HasAnyFlags(RF_NeedLoad), TEXT("Failed to load %s in %s"), *Obj->GetFullName(), *Source->GetFullName()); // in non editor should have been preloaded by GetPreloadDependencies
 		

 
 			}
 		

 

Looks like GetPreloadDependencies is not properly preloading?

I’m having problems with mouse over events on static mesh components via OnBeginCursorOver and OnEndCursorOver and OnClicked.

I have code which has worked over all recent versions up to 4.24.2, but the identical code does not work under 4.25.

The relevant parts are:

[Header file]



UFUNCTION(BlueprintCallable, Category = ViewPoint)
void BlockClicked(UPrimitiveComponent* ClickedComp,FKey key);

UFUNCTION(BlueprintCallable, Category = ViewPoint)
void BlockBeginMouseOver(UPrimitiveComponent* ClickedComp);

UFUNCTION(BlueprintCallable, Category = ViewPoint)
void BlockEndMouseOver(UPrimitiveComponent* ClickedComp);


[Constructor]



// Create dummy root scene component
DummyRoot = CreateDefaultSubobject<USceneComponent>(TEXT("Dummy0"));

// Structure to hold one-time initialization
struct FConstructorStatics
{
ConstructorHelpers::FObjectFinderOptional<UStaticMesh> ViewPointMesh;
FConstructorStatics(): ViewPointMesh(TEXT("/Game/Meshes/ViewPointMarker.ViewPointMarker"))
{
}
};
static FConstructorStatics ConstructorStatics;

// Create static mesh component
BlockMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("BlockMesh0"));
BlockMesh->SetStaticMesh(ConstructorStatics.ViewPointMesh.Get());
BlockMesh->AttachTo(DummyRoot);



//React to mouse clicks
BlockMesh->OnBeginCursorOver.AddDynamic(this, &AViewPoint::BlockBeginMouseOver);
BlockMesh->OnEndCursorOver.AddDynamic(this, &AViewPoint::BlockEndMouseOver);
BlockMesh->OnClicked.AddDynamic(this, &AViewPoint::BlockClicked);




[Functions]



void AViewPoint::BlockClicked(UPrimitiveComponent* ClickedComp,FKey key)
{

if (GEngine)
{
FString message1 = TEXT("BlockClicked ViewPoint Called...");
GEngine->AddOnScreenDebugMessage(-1, 2.f, FColor::Yellow, message1);
}

}



void AViewPoint::BlockBeginMouseOver(UPrimitiveComponent* ClickedComp)
{

if (GEngine)
{

FString message = TEXT("BlockBeginMouseOver ViewPoint Called...");
GEngine->AddOnScreenDebugMessage(-1, 2.f, FColor::Yellow, message);

APlayerController* MyController = GetWorld()->GetFirstPlayerController();
MyController->CurrentMouseCursor = EMouseCursor::Hand;

}

}



void AViewPoint::BlockEndMouseOver(UPrimitiveComponent* ClickedComp)
{

if (GEngine)
{
FString message = TEXT("BlockEndMouseOver ViewPoint Called...");
GEngine->AddOnScreenDebugMessage(-1, 2.f, FColor::Red, message);

APlayerController* MyController = GetWorld()->GetFirstPlayerController();
MyController->CurrentMouseCursor = MyController->DefaultMouseCursor;

}


}




I am finding that unlike in 4.24.2, in 4.25, the static mesh does not react when hovering the mouse over it. Also, when I click the left mouse button, the OnClicked event isn’t called. When I release the left mouse button however, both the BeginMouseOver and EndMouseOver events are called.

Has something changed in 4.25?

I am having lots of problems with compling up from 4.24.3 to 4.25,

First PLATFORM_QUAIL seems to have been removed from the Macro definitions in the engine so I guess that platform is no longer supported.

Now I have several errors - some saying that some fields are to be “made private” i guess that is some form of deprecation.
But i am having problems with “demo” code where it was accessing a variable of AActor which is no longer public in the engine.


     bAutoDestroyWhenFinished = true;

With the error :error C2248: ‘AActor::bAutoDestroyWhenFinished’: cannot access private member declared in class ‘AActor’

Then a lot of these

warning C4996: ‘APlayerState::Score’: This member will be made private. Use GetScore or SetScore instead. Please update your code to the new API before upgrading to the next release, otherwise your project will no longer compile.


IdentityInterface->AddOnControllerPairingChangedDelegate_Handle(FOnControllerPairingChangedDelegate::CreateUObject(this, &USectionNineGameInstance::HandleControllerPairingChanged));

No idea on this one,

1>F:/Development/Section9-V2/Source/SectionNine/SectionNineGameInstance.cpp(59): error C2665: ‘TBaseDelegate<TTypeWrapper<void>,int,FControllerPairingChangedUserInfo,FControllerPairingChangedUserInfo>::CreateUObject’: none of the 2 overloads could convert all the argument types

Hello,

Everything worked fine in 4.24 and now in 4.25 i can’t compile any plugin, i get the following error:

UnrealBuildTool.Main: ERROR: Visual Studio 2017 must be installed in order to build this target.
UnrealBuildTool.Main: BuildException: Visual Studio 2017 must be installed in order to build this target.

I uninstalled VS2017 a long time ago, probably even before 4.24.
It seems strange that 4.25 would need VS17 when 4.24 didn’t.
Any idea ?

Thanks
Cedric

I dunno what ur issue is, but my system is on the low spec side, so I am running engine version 4.23.1 for stability reasons.

in 4.24 had a million crashes, in 4.23.1 zero crashes all day every day.

hope this helps.

God Bless you. May Jesus Christ be Charitable unto you.

Acts 10 : 33 - 48, google it, its Awesome.

Just encountered this too - looks like the parameters to the delegate have changed, so where before your handler definition would have looked like:


void HandleControllerPairingChanged(int GameUserIndex, const FUniqueNetId& PreviousUser, const FUniqueNetId& NewUser);

Now it should use the FControllerPairingChangedUserInfo type like:


void HandleControllerPairingChanged(int GameUserIndex, FControllerPairingChangedUserInfo PreviousUser, FControllerPairingChangedUserInfo NewUser);

And any code inside the handler that used to directly read PreviousUser / NewUser as a FUniqueNetId now can access the same value through the struct’s User property, so PreviousUser.User / NewUser.User.

Getting this error. Tried the “bLegacyPublicIncludePaths = false;” into Build.cs file but that just causes “No such file or directory” on every single include in the entire project. :frowning:

Any ideas on this? Does “bLegacyPublicIncludePaths = false;” have to go anywhere specific? My build file only has 2 things:



using UnrealBuildTool;

public class UE4Sandbox : ModuleRules
{
  public UE4Sandbox(ReadOnlyTargetRules Target) : base(Target)
  {
    bLegacyPublicIncludePaths = false; // complete breaks every #include

      PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;

      PublicDependencyModuleNames.AddRange(new string] { "Core", "CoreUObject", "Engine", "InputCore", "UMG" });
   }
}