Announcement

Collapse
No announcement yet.

4.6 Transition Guide

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

    4.6 Transition Guide

    Dear Community,

    As usual, I wanted to create a place for people to discuss their findings, questions, and solutions about upgrading to 4.6 !

    So if you have any solutions to compile errors, info to share, or questions, feel free to post here!

    Community participation is highly encouraged!

    ~~~

    #1 ~ Constructor Change

    To avoid lots of deprecation warnings, you should open up every .cpp file in your project and replace the old constructor

    Code:
    (const class FPostConstructInitializeProperties& PCIP)
    	: Super(PCIP)
    {
    with

    Code:
    (const FObjectInitializer& ObjectInitializer)
    	: Super(ObjectInitializer)
    {
    ~~~

    #2 ~ Creating Subobjects

    In all of your constructors for every class where you were making subobject components:

    replace

    Code:
    PCIP.CreateDefaultSubobject
    with

    Code:
    ObjectInitializer.CreateDefaultSubobject
    so for example,

    Code:
    UpgradeMesh1 = PCIP.CreateDefaultSubobject<USkeletalMeshComponent>(this, TEXT("UpgradeMesh1"));
    becomes

    Code:
    UpgradeMesh1 = ObjectInitializer.CreateDefaultSubobject<USkeletalMeshComponent>(this, TEXT("UpgradeMesh1"));

    Tip: This one is easy to search and replace!

    ~~~

    #3 ~ No more TSubObjectPtr


    Replace all TSubObjectPtrs with regular ptrs

    For example

    Code:
    UPROPERTY(VisibleDefaultsOnly, Category = "Upgrade Meshes")
    TSubobjectPtr<USkeletalMeshComponent> UpgradeMesh1;
    becomes

    Code:
    private: 
    
    UPROPERTY(VisibleDefaultsOnly, Category = "Upgrade Meshes")
    USkeletalMeshComponent* UpgradeMesh1;
    
    //restore public context below here or put private at the bottom.
    //public:
    Epic Recommendation: Const Accessor

    Epic also recommends you make this pointer private and create a GetUpgradeMesh1() accessor.

    This provides a degree of safety against you losing your core component by changing the pointer to something else, or if someone extends your class and does not understand that this pointer should never be messed with.

    Code:
    //.h
    public:
       USkeletalMeshComponent* GetUpgradeMesh1() const
    Code:
    //.cpp
    USkeletalMeshComponent* AYourClass::GetUpgradeMesh1() const
    {
       return UpgradeMesh1; //note this function is const
    }
    By making this pointer const you prevent people from changing it to point to something else, and causing the Character or other class to lose the ability to find a core component by your established pointer.

    See Character.h for examples, at the very bottom. I chose to use FORCEINLINE but Epic is defining in the .cpp.

    ~~~

    #4 ~ Mesh to GetMesh()

    Replace

    Code:
    YourCharacter->Mesh
    with

    Code:
    YourCharacter->GetMesh()
    everywhere in your code base!


    I recommend doing search and replace for

    Code:
    Mesh->
    and replacing it with

    Code:
    GetMesh()->
    to avoid replacing the word "Mesh" when it is used in other ways.


    Same for CharacterMovement and all other pre-existing components!


    Rama
    Last edited by Rama; 12-11-2014, 01:42 PM.
    100+ UE4 C++ Tutorials on the UE4 Code Wiki, including UE4 Multi-Threading!

    UE4 Marketplace: Melee Weapon Plugin & Compressed Binary Save System Plugin | Rama's C++ AI Jumping Videos | Vertex Snap Editor Plugin

    Visit www.ue4code.com to see lots of videos about my C++ Creations! ♥ Rama

    #2
    The release notes state that
    You now define and use "normal" C++ constructors for your classes. You can use parameterless constructors too now!
    does anyone know what they mean by parameterless constructors? For example when I try to remove all parameters from my own GameMode class I get the following compiler error "Constructor for 'AOwnGameMode' must explicitly initialize the base class 'AGameMode' which does not have a default constructor". Since the GameMode constructor obviously has parameters like
    Code:
    AGameMode::AGameMode(const FObjectInitializer& ObjectInitializer)
    	: Super(ObjectInitializer.DoNotCreateDefaultSubobject(TEXT("Sprite")))
    does this only count for classes with parameterless constructors, even if we don't need an ObjectInitializer?

    Comment


      #3
      Not sure if it helps but according to another thread where an Epic guy explained it the correct way to provide constructors is now

      .h
      Code:
      class Um2uFbxFactory : public UFbxFactory
      {
      	GENERATED_BODY()
      
      	Um2uFbxFactory(const FObjectInitializer& ObjectInitializer);
      
      };
      .cpp
      Code:
      Um2uFbxFactory::Um2uFbxFactory(const FObjectInitializer& ObjectInitializer)
      	: Super(ObjectInitializer)
      {
      }

      Comment


        #4
        Landscape is in its own module now!

        You need to add it to your Build.cs file:

        PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore","AIModule","RenderCore","Landscape" });

        Last edited by Devero; 12-03-2014, 10:20 PM.
        W3 Studios

        Comment


          #5
          I've started adding lots of updates to my original post.

          So far this process of upgrading to 4.6 is quite smooth!

          I'm explaining everything I am having to do in my original post, and so far it is mostly copy paste, yay!

          Rama
          100+ UE4 C++ Tutorials on the UE4 Code Wiki, including UE4 Multi-Threading!

          UE4 Marketplace: Melee Weapon Plugin & Compressed Binary Save System Plugin | Rama's C++ AI Jumping Videos | Vertex Snap Editor Plugin

          Visit www.ue4code.com to see lots of videos about my C++ Creations! ♥ Rama

          Comment


            #6
            Slate Focus Changes

            Focusing of input has been generalized to include all controller types as well as the keyboard and mouse, yay!

            this function needs to be changed everywhere

            from

            Code:
            DEPRECATED(4.6, "SWidget::OnKeyboardFocusReceived() is deprecated, implement SWidget::OnFocusReceived() instead.")
            virtual FReply OnKeyboardFocusReceived(const FGeometry& MyGeometry, const FKeyboardFocusEvent& InFocusEvent);
            to

            Code:
            virtual FReply OnFocusReceived(const FGeometry& MyGeometry, const FFocusEvent& InFocusEvent) override;

            same for these others!

            Code:
            /**
             * Called when this widget loses focus.  This event does not bubble.
             *
             * @param InFocusEvent The FocusEvent
             */
            virtual void OnFocusLost(const FFocusEvent& InFocusEvent);
            
            DEPRECATED(4.6, "SWidget::OnKeyboardFocusLost() is deprecated, implement SWidget::OnFocusLost() instead.")
            virtual void OnKeyboardFocusLost(const FKeyboardFocusEvent& InFocusEvent);
            
            /** Called whenever a focus path is changing on all the widgets within the old and new focus paths */
            virtual void OnFocusChanging(const FWeakWidgetPath& PreviousFocusPath, const FWidgetPath& NewWidgetPath);
            
            DEPRECATED(4.6, "SWidget::OnKeyboardFocusChanging() is deprecated, implement SWidget::OnFocusChanging() instead.")
            virtual void OnKeyboardFocusChanging(const FWeakWidgetPath& PreviousFocusPath, const FWidgetPath& NewWidgetPath);
            Last edited by Rama; 12-04-2014, 02:02 AM.
            100+ UE4 C++ Tutorials on the UE4 Code Wiki, including UE4 Multi-Threading!

            UE4 Marketplace: Melee Weapon Plugin & Compressed Binary Save System Plugin | Rama's C++ AI Jumping Videos | Vertex Snap Editor Plugin

            Visit www.ue4code.com to see lots of videos about my C++ Creations! ♥ Rama

            Comment


              #7
              Victory!

              I've successfully upgraded one of my UE4 projects (Abatron) to 4.6!

              It's a pretty smooth process folks!

              Just ignore the 300-1000 compile errors that you will get each time you compile and keep doing search and replace as I describe in first post and you will be set!



              Thank you for 4.6 Epic!

              Rama
              100+ UE4 C++ Tutorials on the UE4 Code Wiki, including UE4 Multi-Threading!

              UE4 Marketplace: Melee Weapon Plugin & Compressed Binary Save System Plugin | Rama's C++ AI Jumping Videos | Vertex Snap Editor Plugin

              Visit www.ue4code.com to see lots of videos about my C++ Creations! ♥ Rama

              Comment


                #8
                thanks Rama
                should make it a bit easier for people, good work as always
                tegleg.co.uk - indie electronic music label
                Android + HTML5 WIP Physics Game
                PC Games - Android Apps

                Comment


                  #9
                  Dort forget to add that GENERATED_BODY replaces GENERATED_CLASS_BODY and the default visibility is now private.
                  Also you have to declare your constructors in the header!

                  Comment


                    #10
                    Originally posted by ultitech_David View Post
                    Dort forget to add that GENERATED_BODY replaces GENERATED_CLASS_BODY and the default visibility is now private.
                    Also you have to declare your constructors in the header!
                    Example posted here:

                    https://forums.unrealengine.com/show...l=1#post181552

                    Comment


                      #11
                      Rama you have a mistake in #3, I don't think the method should be private...

                      Can you explain how to use GENERATED_BODY? I always get an error with my constructor after that, that it is already implemented.

                      Comment


                        #12
                        Originally posted by Rama View Post
                        I recommend doing search and replace for

                        Code:
                        Mesh->
                        and replacing it with

                        Code:
                        GetMesh()->
                        to avoid replacing the word "Mesh" when it is used in other ways.
                        This is still going to catch things like SkeletalMesh-> and turn them into SkeletalGetMesh()->.

                        Use whole word search instead.

                        Comment


                          #13
                          Originally posted by Devero View Post
                          Landscape is in its own module now!

                          You need to add it to your Build.cs file:

                          PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore","AIModule","RenderCore","Landscape" });

                          Header is also now available here instead.
                          Code:
                          #include "Runtime/Landscape/Classes/Landscape.h"

                          Comment


                            #14
                            Seems 4.6 hates some of my macros (that I use everywhere) and my project crashes when compiling any blueprint. This will be a long day...

                            -- EDIT --
                            Found the problem: 4.6 seems to have a lower tolerance for circular class references, replacing class names with "REINST_" and "SKEL_" everywhere, which causes crashes. So far it seems to only happen when specifying classes directly in function call nodes on the graph. Promoting them to variables with the class as the default value works around the problem.

                            -- EDIT 2 --

                            Nope, the crashes are back. "Invalid Object in GC". FML.
                            Last edited by pedro_clericuzzi; 12-04-2014, 03:09 PM.

                            Comment


                              #15
                              Originally posted by birdfreeyahoo View Post
                              Rama you have a mistake in #3, I don't think the method should be private...

                              Can you explain how to use GENERATED_BODY? I always get an error with my constructor after that, that it is already implemented.
                              Good find, I have fixed that now!

                              ~~~

                              TO GENERATED_BODY OR NOT TO GENERATED_BODY ?

                              Regarding the GENERATED_BODY part, I am deliberately delaying doing that as I read in the 4.6 notes that waiting till 4.7 was a viable option worthy of consideration.

                              Quoting Epic
                              "GENERATED_BODY replaces GENERATED_UCLASS_BODY and provides additional UObject improvements. More changes are planned for GENERATED_BODY with the 4.7 release and users with existing code may wish to delay switching existing classes until then."

                              Since my code bases are so large I opted to do this, for now, I may make the change later, but I have to get a whole bunch of code bases up and running still.

                              You can be up and running in 4.6 without ding the the GENERATED_BODY change.



                              Nice to hear from everyone! Please do keep sharing your findings!

                              Rama
                              100+ UE4 C++ Tutorials on the UE4 Code Wiki, including UE4 Multi-Threading!

                              UE4 Marketplace: Melee Weapon Plugin & Compressed Binary Save System Plugin | Rama's C++ AI Jumping Videos | Vertex Snap Editor Plugin

                              Visit www.ue4code.com to see lots of videos about my C++ Creations! ♥ Rama

                              Comment

                              Working...
                              X