Announcement

Collapse
No announcement yet.

4.25 Transition Guide

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    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!



    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

    Simply add this line to the build.cs:

    Code:
    bLegacyPublicIncludePaths = false;
    ~~~

    UObjectProperty Becomes FObjectProperty

    (BrUnO XaVIeR explains more below!)

    Code:
    UObjectProperty* ObjProp = Cast<UObjectProperty>(Property);
    becomes

    Code:
    FObjectProperty* ObjProp = CastField<FObjectProperty>(Property);
    ~~~

    Happy Coding!



    Rama
    Last edited by Rama; 05-09-2020, 08:58 PM.
    UE4 Marketplace: Melee Weapon Plugin & Compressed Binary Save System Plugin | Rama's C++ AI Jumping Videos | Vertex Snap Editor Plugin

    ♥ Rama

    #2
    UProperty and all subclasses are not UObjects anymore...


    A weak pointer went from
    Code:
    TWeakObjectPtr<UProperty> myProperty;
    to
    Code:
    TWeakFieldPtr<FProperty> myProperty;

    You can still use
    Code:
    FProperty::StaticClass();
    and
    Code:
    myProperty->IsA( FxxxProperty::StaticClass() )

    You can't use anymore
    Code:
    myProperty->GetOuter();
    you have to use instead
    Code:
    myProperty->GetOwner<UObject>();

    You can't use Cast<> on FProperties like before
    Code:
    CastChecked<UStructProperty>(myProperty);
    Now you have to use a different one:
    Code:
    CastFieldChecked<FStructProperty>(myProperty);
    Last edited by BrUnO XaVIeR; 05-07-2020, 07:40 AM. Reason: little typo
    | Savior | USQLite | FSM | Object Pool | Sound Occlusion | Property Transfer | Magic Nodes | MORE |

    Comment


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

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

      2)
      Shaders no longer have an explicit
      Code:
      virtual bool Serialize(FArchive& Ar) override
      method to serialize.

      This is now instead achieved by wrapping all shader parameters in a LAYOUT_FIELD macro.
      Code:
      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).
      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

      Code:
        DECLARE_EXPORTED_TYPE_LAYOUT(FYourShaderName, YOUR_API, Virtual);
      within the shader declaration and in a .cpp somewhere do
      Code:
      IMPLEMENT_UNREGISTERED_TEMPLATE_TYPE_LAYOUT(, FYourShaderName);
      And in shaders with virtual methods (where the shader will be implemented), you have to call
      Code:
        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).
      Last edited by tommybazar; 05-07-2020, 06:48 AM.

      Comment


        #4
        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 https://forums.unrealengine.com/deve...25-steam-issue

        Comment


          #5
          Originally posted by tommybazar View Post
          1)
          Text

          Any idea for macros like "GETSAFERHISHADER_VERTEX"? They were completely removed.
          Last edited by TheJamsh; 05-07-2020, 08:05 AM. Reason: Removed large quote text to make page more readable.

          Comment


            #6
            Originally posted by tommybazar View Post
            1)
            FImageWriteTask now accepts TArray64 as data instead of a TArray. If you have a regular TArray, pass it in like this:

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

            2)
            Shaders no longer have an explicit
            Code:
            virtual bool Serialize(FArchive& Ar) override
            method to serialize.

            This is now instead achieved by wrapping all shader parameters in a LAYOUT_FIELD macro.
            Code:
            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).
            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

            Code:
             DECLARE_EXPORTED_TYPE_LAYOUT(FYourShaderName, YOUR_API, Virtual);
            within the shader declaration and in a .cpp somewhere do
            Code:
            IMPLEMENT_UNREGISTERED_TEMPLATE_TYPE_LAYOUT(, FYourShaderName);
            And in shaders with virtual methods (where the shader will be implemented), you have to call
            Code:
            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).
            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?

            Comment


              #7
              Originally posted by UnrealXinda View Post

              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:

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

              Originally posted by Bencsizy View Post
              Any idea for macros like "GETSAFERHISHADER_VERTEX"? They were completely removed.
              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
              Last edited by tommybazar; 05-07-2020, 09:36 PM.

              Comment


                #8
                Originally posted by tommybazar View Post

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

                Code:
                TShaderMapRef<FYourShaderName> ComputeShader(GetGlobalShaderMap(ERHIFeatureLevel::SM5));
                FRHIComputeShader* pShaderRHI = ComputeShader.GetComputeShader();
                RHICmdList.SetComputeShader(pShaderRHI);
                OK. So like we can no longer call GetComputeShader() from inside custom shader now? Cause I used to do things like
                Code:
                class FMyShader : public FGlobalShader
                {
                ...
                    void BindShaderBuffer(FRHICommandList& RHICmdList, FUnorderedAccessViewRHIRef OutputBufferUAV)
                    {
                        SetUAVParameter(RHICmdList, GetComputeShader(), OutputBuffer, OutputBufferUAV);
                    }
                }

                Comment


                  #9
                  Originally posted by UnrealXinda View Post

                  OK. So like we can no longer call GetComputeShader() from inside custom shader now? Cause I used to do things like.........
                  Use this:
                  Code:
                  RHICmdList.GetBoundComputeShader();

                  Comment


                    #10
                    Originally posted by tommybazar View Post

                    Code:
                    TShaderMapRef<FYourShaderName> ComputeShader(GetGlobalShaderMap(ERHIFeatureLevel::SM5));
                    FRHIComputeShader* pShaderRHI = ComputeShader.GetComputeShader();
                    RHICmdList.SetComputeShader(pShaderRHI);
                    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?

                    Comment


                      #11
                      Originally posted by Bencsizy View Post

                      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();

                      Comment


                        #12
                        If you were using
                        Code:
                        UProperty*
                        for wildcard property passing in Blueprint, the transition that worked for me was
                        Code:
                        TFieldPath<FProperty>
                        e.g.
                        Code:
                        UFUNCTION(BlueprintCallable, CustomThunk, meta = (CustomStructureParam = "AnyStruct"))
                        static bool ReadAnyStruct(TFieldPath<FProperty> AnyStruct);
                        Also in my case, stepping through a custom thunk,
                        Code:
                        ExactCast
                        became
                        Code:
                        CastField
                        e.g.
                        Code:
                        FStructProperty* StructProp = CastField<FStructProperty>(Stack.MostRecentProperty);
                        Plugins: GES - Node.js - TensorFlow - Socket.io Client - ZipUtility - Leap Motion - Hydra - Myo

                        Comment


                          #13
                          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:
                          Code:
                          TArray<uint8> *RawDataPtr = NULL;
                          TArray<uint8>& RawData = *RawDataPtr;
                          if (ImageWrapper->GetRaw(ERGBFormat::RGBA, 8, RawData))
                          Should be changed to:
                          Code:
                          TArray64<uint8> *RawData;
                          if (ImageWrapper->GetRaw(ERGBFormat::RGBA, 8, RawData))
                          I ran into this issue because I was using ImageWrapper for a UTexture2DDynamic.

                          Comment


                            #14
                            Any ideas how to fix this kind of error:

                            Code:
                            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

                            Code:
                             
                            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?
                            Last edited by unit23; 05-19-2020, 04:21 PM.
                            [LEGENDS of EPICA][Twitter][FB][YT][Vimeo][Reallusion Technical Expert]

                            Comment


                              #15
                              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]

                              Code:
                              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]

                              Code:
                              // 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]

                              Code:
                              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?

                              Comment

                              Working...
                              X