Announcement

Collapse
No announcement yet.

4.7 C++ Transition Guide

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

    #16
    This line is of importance : "Branching Points refactor. BranchingPoints are now regular AnimNotifies, with their MontageTickType set to 'BranchingPoint' instead of 'Queued'."

    This means that if you use a C++ class for your animation instance, and you have previously declared functions like: MontageBranchingPoint_JumpLeaveGround, you'll have to rename them in AnimNotify_JumpLeaveGround.
    My game dev blog : http://www.emidee.net/

    Comment


      #17
      How to Find a Path in 4.7 Without UNavigationComponent

      UNavigationComponent has been removed, here are two ways you can find paths in 4.7!

      Two Options

      1. Use the static accessible Navigation System

      Code:
      UNavigationSystem::FindPathToLocationSynchronously(...)

      NavigationSystem.h

      Code:
      /** Finds path instantly, in a FindPath Synchronously. 
      	 *	@param PathfindingContext could be one of following: NavigationData (like Navmesh actor), Pawn or Controller. This parameter determines parameters of specific pathfinding query */
      	UFUNCTION(BlueprintCallable, Category = "AI|Navigation", meta = (HidePin = "WorldContext", DefaultToSelf = "WorldContext"))
      	static UNavigationPath* FindPathToLocationSynchronously(UObject* WorldContext, const FVector& PathStart, const FVector& PathEnd, AActor* PathfindingContext = NULL, TSubclassOf<UNavigationQueryFilter> FilterClass = NULL);
      
      	/** Finds path instantly, in a FindPath Synchronously. Main advantage over FindPathToLocationSynchronously is that 
      	 *	the resulting path with automatically get updated if goal actor moves more then TetherDistance away from last path node
      	 *	@param PathfindingContext could be one of following: NavigationData (like Navmesh actor), Pawn or Controller. This parameter determines parameters of specific pathfinding query */
      	UFUNCTION(BlueprintCallable, Category = "AI|Navigation", meta = (HidePin = "WorldContext", DefaultToSelf = "WorldContext"))
      	static UNavigationPath* FindPathToActorSynchronously(UObject* WorldContext, const FVector& PathStart, AActor* GoalActor, float TetherDistance = 50.f, AActor* PathfindingContext = NULL, TSubclassOf<UNavigationQueryFilter> FilterClass = NULL);
      
      //----------------------------------------------------------------------//
      	// Public querying interface                                                                
      	//----------------------------------------------------------------------//
      	/** 
      	 *	Synchronously looks for a path from @fLocation to @EndLocation for agent with properties @AgentProperties. NavData actor appropriate for specified 
      	 *	FNavAgentProperties will be found automatically
      	 *	@param ResultPath results are put here
      	 *	@param NavData optional navigation data that will be used instead of the one that would be deducted from AgentProperties
      	 *  @param Mode switch between normal and hierarchical path finding algorithms
      	 */
      	FPathFindingResult FindPathSync(const FNavAgentProperties& AgentProperties, FPathFindingQuery Query, EPathFindingMode::Type Mode = EPathFindingMode::Regular);
      
      	/** 
      	 *	Does a simple path finding from @StartLocation to @EndLocation on specified NavData. If none passed MainNavData will be used
      	 *	Result gets placed in ResultPath
      	 *	@param NavData optional navigation data that will be used instead main navigation data
      	 *  @param Mode switch between normal and hierarchical path finding algorithms
      	 */
      	FPathFindingResult FindPathSync(FPathFindingQuery Query, EPathFindingMode::Type Mode = EPathFindingMode::Regular);
      
      	/** 
      	 *	Asynchronously looks for a path from @StartLocation to @EndLocation for agent with properties @AgentProperties. NavData actor appropriate for specified 
      	 *	FNavAgentProperties will be found automatically
      	 *	@param ResultDelegate delegate that will be called once query has been processed and finished. Will be called even if query fails - in such case see comments for delegate's params
      	 *	@param NavData optional navigation data that will be used instead of the one that would be deducted from AgentProperties
      	 *	@param PathToFill if points to an actual navigation path instance than this instance will be filled with resulting path. Otherwise a new instance will be created and 
      	 *		used in call to ResultDelegate
      	 *  @param Mode switch between normal and hierarchical path finding algorithms
      	 *	@return request ID
      	 */
      	uint32 FindPathAsync(const FNavAgentProperties& AgentProperties, FPathFindingQuery Query, const FNavPathQueryDelegate& ResultDelegate, EPathFindingMode::Type Mode = EPathFindingMode::Regular);
      
      	/** Removes query indicated by given ID from queue of path finding requests to process. */
      	void AbortAsyncFindPathRequest(uint32 AsynPathQueryID);
      	
      	/** 
      	 *	Synchronously check if path between two points exists
      	 *  Does not return path object, but will run faster (especially in hierarchical mode)
      	 *  @param Mode switch between normal and hierarchical path finding algorithms. @note Hierarchical mode ignores QueryFilter
      	 *	@return true if path exists
      	 */
      	bool TestPathSync(FPathFindingQuery Query, EPathFindingMode::Type Mode = EPathFindingMode::Regular, int32* NumVisitedNodes = NULL) const;
      
      	/** Finds random point in navigable space
      	 *	@param ResultLocation Found point is put here
      	 *	@param NavData If NavData == NULL then MainNavData is used.
      	 *	@return true if any location found, false otherwise */
      	bool GetRandomPoint(FNavLocation& ResultLocation, ANavigationData* NavData = NULL, TSharedPtr<const FNavigationQueryFilter> QueryFilter = NULL);
      
      	/** Finds random point in navigable space restricted to Radius around Origin
      	 *	@param ResultLocation Found point is put here
      	 *	@param NavData If NavData == NULL then MainNavData is used.
      	 *	@return true if any location found, false otherwise */
      	bool GetRandomPointInRadius(const FVector& Origin, float Radius, FNavLocation& ResultLocation, ANavigationData* NavData = NULL, TSharedPtr<const FNavigationQueryFilter> QueryFilter = NULL) const;
      2. Get the Nav data within your follow comp and use instanced versions

      Code:
      bool UYourFollowComp::GetRandomPointInRadius(const FVector& Origin, float Radius, FVector& OutResult)
      {
      	if (!MovementComp) 
      	{
      		return false;
      	}
      	//~~~~~~~~~~~~~~~~~~
      	
      	//Agent Properties
      	const FNavAgentProperties& AgentProperties = MovementComp->GetNavAgentPropertiesRef();
      	const ANavigationData * NavData = GetNavDataForProps(AgentProperties);
      	if (!NavData) 
      	{
      		return false;
      	}
      	
      	//Now here you can use Nav Data functions!
      	
      	NavData->YourDesiredFunction()
      }
      NavData.h

      Code:
      /** 
      	 *	Synchronously looks for a path from @StartLocation to @EndLocation for agent with properties @AgentProperties. NavMesh actor appropriate for specified 
      	 *	FNavAgentProperties will be found automatically
      	 *	@param ResultPath results are put here
      	 *	@return true if path has been found, false otherwise
      	 *
      	 *	@note don't make this function virtual! Look at implementation details and its comments for more info.
      	 */
      	FORCEINLINE FPathFindingResult FindPath(const FNavAgentProperties& AgentProperties, const FPathFindingQuery& Query) const
      	{
      		check(FindPathImplementation);
      		// this awkward implementation avoids virtual call overhead - it's possible this function will be called a lot
      		return (*FindPathImplementation)(AgentProperties, Query);
      	}
      
      	/** 
      	 *	Synchronously looks for a path from @StartLocation to @EndLocation for agent with properties @AgentProperties. NavMesh actor appropriate for specified 
      	 *	FNavAgentProperties will be found automatically
      	 *	@param ResultPath results are put here
      	 *	@return true if path has been found, false otherwise
      	 *
      	 *	@note don't make this function virtual! Look at implementation details and its comments for more info.
      	 */
      	FORCEINLINE FPathFindingResult FindHierarchicalPath(const FNavAgentProperties& AgentProperties, const FPathFindingQuery& Query) const
      	{
      		check(FindHierarchicalPathImplementation);
      		// this awkward implementation avoids virtual call overhead - it's possible this function will be called a lot
      		return (*FindHierarchicalPathImplementation)(AgentProperties, Query);
      	}

      Enjoy!

      Rama
      Last edited by Rama; 02-25-2015, 08:30 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

      Comment


        #18
        Regarding the 'no appropriate constructor' errors when trying to use no-argument constructors. It appears the release notes were a bit unclear about this.

        I've had a look through the engine code and concluded that it depends on what class you're deriving from. Directly from UObject, fine. Otherwise, unsurprisingly, you can only declare a constructor without an FObjectInitializer if your base class also has one. It looks like any engine classes which have been updated to use GENERATED_BODY have been given a default constructor, whilst those still using GENERATED_UCLASS_BODY have not.

        AActor has been updated, however I checked a few other engine classes and it looks like most of them haven't. I'm guessing this will change over time, but I'm not certain.

        Comment


          #19
          Well it should be trivial to add a constructor to parent classes.

          Comment


            #20
            Originally posted by DamirH View Post
            Well it should be trivial to add a constructor to parent classes.
            I don't think anyone is going to be rebuilding the engine from source every time they want to derive from another class, just to avoid having to write an extra argument into their constructor.

            Comment


              #21
              Bah, I misunderstood what you wrote... Yeah, that sucks indeed, but the old way with FObjectInitializer still works so you can fall back to that for classes that don't have the constructor yet.

              Comment


                #22
                I was just bitten by DrawDynamicElements being removed from scene proxies. It seems it was deprecated in UE 4.5 and was planned to be removed since then. It's shame that Epic didn't add a deprecation warning to those using DrawDynamicElements (to cause compiler warning) in the meantime but it wasn't too difficult to track down the reason my meshes weren't being displayed.

                It's a simple enough change to make since the replacement function is very similar but you can see what I had to do at https://github.com/volumesoffun/cubi...ommit/2a81df4b

                I believe that the wiki tutorial on procedural mesh generation will need updating too.
                WIP: Cubiquity for UE4 - A voxel terrain plugin

                Comment


                  #23
                  Originally posted by milliams View Post
                  I was just bitten by DrawDynamicElements being removed from scene proxies. It seems it was deprecated in UE 4.5 and was planned to be removed since then. It's shame that Epic didn't add a deprecation warning to those using DrawDynamicElements (to cause compiler warning) in the meantime but it wasn't too difficult to track down the reason my meshes weren't being displayed.

                  It's a simple enough change to make since the replacement function is very similar but you can see what I had to do at https://github.com/volumesoffun/cubi...ommit/2a81df4b

                  I believe that the wiki tutorial on procedural mesh generation will need updating too.
                  Thanks for sharing Milliams, very important info!

                  For anyone who is interested, here's Epic's 4.7 Release note on this topic:

                  "GetDynamicMeshElements path on scene proxies is enabled by default
                  PreRenderView / DrawDynamicElements are no longer used and have been removed"


                  ~~~

                  Request

                  Milliams or someone else who is currently doing dynamic mesh stuff, can you update the Procedural Mesh Generation wiki to 4.7 ?

                  https://wiki.unrealengine.com/Proced...esh_Generation

                  I want to make sure a fully rigorous test case is used to verify the new code and I dont have such a test case right now.

                  Rama
                  Last edited by Rama; 02-26-2015, 09:43 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

                  Comment


                    #24
                    Regarding constructors, it seems there's no way to replace AYourHud(const FObjectInitializer& ObjectInitializer) and AYourGameMode(const FObjectInitializer& ObjectInitializer) with versions without FObjectInitializer's.
                    You must keep them for HUD and GameMode.

                    Comment


                      #25
                      I could swear I replaced it in my game mode. Will double check when I'm in the office tomorrow.

                      Comment


                        #26
                        I can confirm that with Game Mode and GameState you still need to use an ObjectInitializer.

                        As kamrann said further up, it depends if the inherited class uses GENERATED_BODY or GENERATED_UCLASS_BODY. With GameState and GameMode thats the case. Looking at HUD, I also see GENERATED_UCLASS_BODY so you would still need an ObjectInitializer for that too.
                        - Martin

                        A Simple Prototype

                        https://www.martinegger.org/

                        Technical Producer

                        Comment


                          #27
                          Originally posted by DamirH View Post
                          As I learned the hard way, not only are you not required to add a call to Super() in the constructor, but if you do, your editor will crash on startup.
                          Hi DamirH,
                          I've tried adding Super() to constructor initialization list in 4.7 to the above code in fresh project and I had not reproduced any crash. Is it something that was re-occuring to you? Could you provide more details how to reproduce the crash?

                          We'd like to investigate, but without repro it's not possible.

                          Thanks,
                          Jarek

                          Comment


                            #28
                            Simply use the normal constructor with the ObjectInitializer. It won't kill you doing so, and you would save nothing by using the default constructor.

                            Comment


                              #29
                              Originally posted by Jarek View Post
                              Hi DamirH,
                              I've tried adding Super() to constructor initialization list in 4.7 to the above code in fresh project and I had not reproduced any crash. Is it something that was re-occuring to you? Could you provide more details how to reproduce the crash?

                              We'd like to investigate, but without repro it's not possible.

                              Thanks,
                              Jarek
                              Hey Jarek,

                              It was recurring, I couldn't launch the project all, ever. I am not in the office right now so I'll be able to post code in the morning.

                              EDIT:

                              Ok, I can replicate it. Editor loads up to 70% then crashes.

                              Code

                              Crash Log
                              Last edited by DamirH; 02-28-2015, 01:00 AM.

                              Comment


                                #30
                                4.7 Class Constructors

                                Dear DamirH,

                                Is there a reason you are avoiding the ObjectInitializer constructor?

                                ~~~

                                4.7 Class Constructors

                                For those who might be confused about all this:

                                You can easily create a constructor in 4.7 using this arrangement:

                                .h
                                Code:
                                UCLASS()
                                class AYourClass : public AYourSuperClass
                                {
                                	GENERATED_BODY()
                                public: 
                                	AYourClass(const FObjectInitializer& ObjectInitializer);
                                
                                };
                                .cpp
                                Code:
                                AYourClass::AYourClass(const FObjectInitializer& ObjectInitializer)
                                	: Super(ObjectInitializer)
                                {
                                   //add your constructor code / other constructor function calls here
                                }
                                Enjoy!

                                Rama
                                Last edited by Rama; 02-28-2015, 08:58 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

                                Working...
                                X