Object Move Back and Forth on Timeline Ue4

Github Link: https://github.com/Harrison1/unrealcpp/tree/master/OpenDoorTimelineCurve

For this tutorial we are using the standard first person C++ template with the starter content.

In this Unreal Engine 4 C++ tutorial we will learn how to open a door using a timeline and curve float when the player presses a key. The door will open depending on which way the player is facing.

First, inside the editor add an Action key by going to Edit > Project Settins > Input > Action Mappings. Add an an action and call it Action and bind it to to the E key.

Next, in your content folder, right click, go to Miscellaneous > Curve and create new Curve Float. Open the curve float and create a new key by right clicking and selecting new key. In the top left set the values of the first key to have the values of 0 for Time and Value. Create a second key and set its Time value to 1.0 and its Value property to 90.0. Hold SHIFT, select both keys and then click Auto in the top bar to give the curve a smooth beginning and end.

Next, in your content folder, right click, go to User Interface and select Widget Blueprint. Inside the Widget Blueprint drag and drop an image property into the viewport. For the source you can add the image below or any image you want. At the top of the details panel for the image name the property helpimage.

feel free to use this image you want

press e to open

Before we create a new actor, let's add to out build file so we can use UMG widgets. In your Build.cs file add UMG, Slate, and SlateCore;

UnrealCpp.Build.cs

                          using              UnrealBuildTool;              public              class              UnrealCPP              :                              ModuleRules                            {              public              UnrealCPP              (ReadOnlyTargetRules Target)              :              base              (Target)              {              PCHUsage              =              PCHUsageMode.UseExplicitOrSharedPCHs;              PublicDependencyModuleNames.              AddRange              (              new              string[              ]              {              "Core"              ,              "CoreUObject"              ,              "Engine"              ,              "InputCore"              ,              "HeadMountedDisplay"              ,              "UMG"              ,              "Slate"              ,              "SlateCore"              }              )              ;              }              }                      

Next, create a new actor class and call it whatever you want, in this tutorial I will call it OpenDoorTimelineCurve.

First, in the .h file let's #include the TimelineComponent.h" at the top of the file. Make sure it comes before your Actor's generated.h file.

include TimelineComponent

                                          #                include                "CoreMinimal.h"                                            #                include                "GameFramework/Actor.h"                            // include before generated file                              #                include                "Components/TimelineComponent.h"                                            #                include                "OpenDoorWithLerp.generated.h"                                    

Next, we'll setup our variables. We'll create some variables and functions to use and track throughout our .cpp file.

Our Header Properties and Functions

                          .              .              .              UPROPERTY              (EditAnywhere)              UStaticMeshComponent*              Door;              UPROPERTY              (EditAnywhere)              UStaticMeshComponent*              DoorFrame;              UPROPERTY              (EditAnywhere)              UCurveFloat              *DoorCurve;              UFUNCTION              (              )              void              ControlDoor              (              )              ;              UFUNCTION              (              )              void              ToggleDoor              (              )              ;              UFUNCTION              (              )              void              SetState              (              )              ;              bool              Open;              bool              ReadyState;              float              RotateValue;              float              CurveFloatValue;              float              TimelineValue;              FRotator DoorRotation;              FTimeline MyTimeline;                      

Next, we'll move into the Actor's .cpp file. We'll first want to #include the the KismetMathLibrary and GameplayStatics" header file. We'll use Kismet functions in the toggle function.

include files

                                          #                include                "Kismet/KismetMathLibrary.h"                                            #                include                "Kismet/GameplayStatics.h"                                    

In the constructor function we will set our default variables. First, we'll set our Open bool to false and our ReadyState to true. Then we'll setup our DoorFrame as the RootComponent and then attach our Door mesh to it.

constructor function

                          AOpenDoorTimelineCurve              ::              AOpenDoorTimelineCurve              (              )              {              PrimaryActorTick.bCanEverTick              =              true              ;              Open              =              false              ;              ReadyState              =              true              ;              DoorFrame              =              CreateDefaultSubobject<UStaticMeshComponent>              (              TEXT              (              "DoorFrame"              )              )              ;              RootComponent              =              DoorFrame;              Door              =              CreateDefaultSubobject<UStaticMeshComponent>              (              TEXT              (              "My Mesh"              )              )              ;              Door->              SetupAttachment              (RootComponent)              ;              }                      

Next, in the BeginPlay function we will setup our Timeline component. In the editor we'll set our DoorCurve to be the float curve we created earlier. So, if the DoorCurve is not NULL, we'll setup our callback functions and connect them to our timeline. When the timeline is moving through the DoorCurve we will call the ControlDoor function and when the timeline is finished we will call the SetState function.

BeginPlay function

                          void              AOpenDoorTimelineCurve              ::              BeginPlay              (              )              {              Super              ::              BeginPlay              (              )              ;              RotateValue              =              1.0f              ;              if              (DoorCurve)              {              FOnTimelineFloat TimelineCallback;              FOnTimelineEventStatic TimelineFinishedCallback;              TimelineCallback.              BindUFunction              (              this              ,              FName              (              "ControlDoor"              )              )              ;              TimelineFinishedCallback.              BindUFunction              (              this              ,              FName{              TEXT              (              "SetState"              )              }              )              ;              MyTimeline.              AddInterpFloat              (DoorCurve,              TimelineCallback)              ;              MyTimeline.              SetTimelineFinishedFunc              (TimelineFinishedCallback)              ;              }              }                      

In the Tick function we have to connect our Timeline to DeltaTime;

Tick function

                          void              AOpenDoorTimelineCurve              ::              Tick              (              float              DeltaTime)              {              Super              ::              Tick              (DeltaTime)              ;              MyTimeline.              TickTimeline              (DeltaTime)              ;              }                      

Next, let's create the ControlDoor function. This function will get the playback position of the timeline, then grab the value that number has on the float curve, and then set the relative rotation for the door. The RotateValue is set in ToggleDoor function that we'll create later, but the RotateValue will determine the direction in which the door opens.

ControlDoor function

                          void              AOpenDoorTimelineCurve              ::              ControlDoor              (              )              {              TimelineValue              =              MyTimeline.              GetPlaybackPosition              (              )              ;              CurveFloatValue              =              RotateValue*DoorCurve->              GetFloatValue              (TimelineValue)              ;              FQuat NewRotation              =              FQuat              (              FRotator              (              0.f              ,              CurveFloatValue,              0.f              )              )              ;              Door->              SetRelativeRotation              (NewRotation)              ;              }                      

Next, we'll create the SetState function to simply set ReadyState to true. We will only be able to open or close the door when ReadyState is true.

SetState function

                          void              AOpenDoorTimelineCurve              ::              SetState              (              )              {              ReadyState              =              true              ;              }                      

Next, we'll create the ToggleDoor function. First, we'll check if ReadyState is true. If ReadyState is true we will toggle Open and get the Door's current rotation. Next, we will get the direction the player is facing, determining if they are in front or behind the door. We will use the KismetMathLibrary's function LessLess_VectorRotator to get an X coordinate that is either positive or negative. If Open is true we will set RotateValue to 1.0f or -1.0f depending on the direction and then set ReadyState to false and then play the timeline from the start. If Open is false we will set ReadyState to false and reverse the timeline.

ToggleDoor function

                          void              AOpenDoorTimelineCurve              ::              ToggleDoor              (              )              {              if              (ReadyState)              {              Open              =              !Open;              DoorRotation              =              Door->RelativeRotation;              APawn*              OurPawn              =              UGameplayStatics              ::              GetPlayerPawn              (              this              ,              0              )              ;              FVector PawnLocation              =              OurPawn->              GetActorLocation              (              )              ;              FVector Direction              =              GetActorLocation              (              )              -              PawnLocation;              Direction              =              UKismetMathLibrary              ::              LessLess_VectorRotator              (Direction,              GetActorRotation              (              )              )              ;              if              (Open)              {              if              (Direction.X              >              0.0f              )              {              RotateValue              =              1.0f              ;              }              else              {              RotateValue              =              -              1.0f              ;              }              ReadyState              =              false              ;              MyTimeline.              PlayFromStart              (              )              ;              }              else              {              ReadyState              =              false              ;              MyTimeline.              Reverse              (              )              ;              }              }              }                      

Next, let's move into the character header file. at the tope include the new door class the UserWidget header file.

include in the character header file. The path to your door class might be different, so use your path.

                                          #                include                "CoreMinimal.h"                                            #                include                "GameFramework/Character.h"                            // include these two                              #                include                "OpenDoorTimelineCurve/OpenDoorTimelineCurve.h"                                            #                include                "Blueprint/UserWidget.h"                                            #                include                "UnrealCPPCharacter.generated.h"                                    

Then, we will be using the Tick function so we need to override it and then add our properties and add our OnAction function.

character setup

                          .              .              .              protected              :              virtual              void              BeginPlay              (              )              ;              // add tick override              virtual              void              Tick              (              float              DeltaSeconds)              override;              public              :              /** Base turn rate, in deg/sec. Other scaling may affect final turn rate. */              UPROPERTY              (VisibleAnywhere,              BlueprintReadOnly,              Category=Camera)              float              BaseTurnRate;              /** Base look up/down rate, in deg/sec. Other scaling may affect final rate. */              UPROPERTY              (VisibleAnywhere,              BlueprintReadOnly,              Category=Camera)              float              BaseLookUpRate;              /** Gun muzzle's offset from the characters location */              UPROPERTY              (EditAnywhere,              BlueprintReadWrite,              Category=Gameplay)              FVector GunOffset;              /** Projectile class to spawn */              UPROPERTY              (EditDefaultsOnly,              Category=Projectile)              TSubclassOf<              class              AUnrealCPPProjectile              >              ProjectileClass;              /** Sound to play each time we fire */              UPROPERTY              (EditAnywhere,              BlueprintReadWrite,              Category=Gameplay)              class              USoundBase              *              FireSound;              /** AnimMontage to play each time we fire */              UPROPERTY              (EditAnywhere,              BlueprintReadWrite,              Category              =              Gameplay)              class              UAnimMontage              *              FireAnimation;              // declare float curve              UPROPERTY              (EditAnywhere)              class              AOpenDoorTimelineCurve              *              CurrentDoor;              // Reference UMG Asset in the Editor              UPROPERTY              (EditAnywhere)              TSubclassOf<              class              UUserWidget              >              HelpWidgetClass;              // declare widget              class              UUserWidget              *              InfoWidget;              protected              :              /** Fires a projectile. */              void              OnFire              (              )              ;              /** Action Function */              void              OnAction              (              )              ;                      

Next, in the character .cpp file #include DrawDebugHelpers.h to so we can visualize the line trace.

include DrawDebugHelpers.h

                                          #                include                "DrawDebugHelpers.h"                                    

In the constructor function set CurrentDoor to NULL.

constructor function

                          AUnrealCPPCharacter              ::              AUnrealCPPCharacter              (              )              {              // Set size for collision capsule              GetCapsuleComponent              (              )              ->              InitCapsuleSize              (              55.f              ,              96.0f              )              ;              // set our turn rates for input              BaseTurnRate              =              45.f              ;              BaseLookUpRate              =              45.f              ;              // Create a CameraComponent                            FirstPersonCameraComponent              =              CreateDefaultSubobject<UCameraComponent>              (              TEXT              (              "FirstPersonCamera"              )              )              ;              FirstPersonCameraComponent->              SetupAttachment              (              GetCapsuleComponent              (              )              )              ;              FirstPersonCameraComponent->RelativeLocation              =              FVector              (              -              39.56f              ,              1.75f              ,              64.f              )              ;              // Position the camera              FirstPersonCameraComponent->bUsePawnControlRotation              =              true              ;              // Create a mesh component that will be used when being viewed from a '1st person' view (when controlling this pawn)              Mesh1P              =              CreateDefaultSubobject<USkeletalMeshComponent>              (              TEXT              (              "CharacterMesh1P"              )              )              ;              Mesh1P->              SetOnlyOwnerSee              (              true              )              ;              Mesh1P->              SetupAttachment              (FirstPersonCameraComponent)              ;              Mesh1P->bCastDynamicShadow              =              false              ;              Mesh1P->CastShadow              =              false              ;              Mesh1P->RelativeRotation              =              FRotator              (              1.9f              ,              -              19.19f              ,              5.2f              )              ;              Mesh1P->RelativeLocation              =              FVector              (              -              0.5f              ,              -              4.4f              ,              -              155.7f              )              ;              // Create a gun mesh component              FP_Gun              =              CreateDefaultSubobject<USkeletalMeshComponent>              (              TEXT              (              "FP_Gun"              )              )              ;              FP_Gun->              SetOnlyOwnerSee              (              true              )              ;              // only the owning player will see this mesh              FP_Gun->bCastDynamicShadow              =              false              ;              FP_Gun->CastShadow              =              false              ;              // FP_Gun->SetupAttachment(Mesh1P, TEXT("GripPoint"));              FP_Gun->              SetupAttachment              (RootComponent)              ;              FP_MuzzleLocation              =              CreateDefaultSubobject<USceneComponent>              (              TEXT              (              "MuzzleLocation"              )              )              ;              FP_MuzzleLocation->              SetupAttachment              (FP_Gun)              ;              FP_MuzzleLocation->              SetRelativeLocation              (              FVector              (              0.2f              ,              48.4f              ,              -              10.6f              )              )              ;              // Default offset from the character location for projectiles to spawn              GunOffset              =              FVector              (              100.0f              ,              0.0f              ,              10.0f              )              ;              // Note: The ProjectileClass and the skeletal mesh/anim blueprints for Mesh1P, FP_Gun, and VR_Gun                            // are set in the derived blueprint asset named MyCharacter to avoid direct content references in C++.              CurrentDoor              =              NULL              ;              }                      

In the BeginPlay function, we will setup the UserWidget and add it to the viewport.

BeginPlay function

                          void              AUnrealCPPCharacter              ::              BeginPlay              (              )              {              // Call the base class                            Super:                              :                BeginPlay                (                )                            ;              //Attach gun mesh component to Skeleton, doing it here because the skeleton is not yet created in the constructor              FP_Gun->              AttachToComponent              (Mesh1P,              FAttachmentTransformRules              (EAttachmentRule::SnapToTarget,              true              )              ,              TEXT              (              "GripPoint"              )              )              ;              Mesh1P->              SetHiddenInGame              (              false              ,              true              )              ;              if              (HelpWidgetClass)              {              InfoWidget              =              CreateWidget<UUserWidget>              (              GetWorld              (              )              ,              HelpWidgetClass)              ;              if              (InfoWidget)              {              InfoWidget->              AddToViewport              (              )              ;              }              }              }                      

In the Tick function we will draw a line trace every frame to see if we are returning a door. If the Hit actor is a door then we will set CurrentDoor to the current actor and display our help image.

Tick function

                          void              AUnrealCPPCharacter              ::              Tick              (              float              DeltaTime)              {              Super              ::              Tick              (DeltaTime)              ;              FHitResult Hit;              FVector Start              =              FirstPersonCameraComponent->              GetComponentLocation              (              )              ;              FVector ForwardVector              =              FirstPersonCameraComponent->              GetForwardVector              (              )              ;              FVector End              =              (              (ForwardVector              *              200.f              )              +              Start)              ;              FCollisionQueryParams CollisionParams;              DrawDebugLine              (              GetWorld              (              )              ,              Start,              End,              FColor::Green,              false              ,              1              ,              0              ,              1              )              ;              if              (              GetWorld              (              )              ->              LineTraceSingleByChannel              (Hit,              Start,              End,              ECC_Visibility,              CollisionParams)              )              {              if              (Hit.bBlockingHit)              {              if              (Hit.              GetActor              (              )              ->              GetClass              (              )              ->              IsChildOf              (              AOpenDoorTimelineCurve              ::              StaticClass              (              )              )              )              {              InfoWidget->              GetWidgetFromName              (              "helpimage"              )              ->              SetVisibility              (ESlateVisibility::Visible)              ;              CurrentDoor              =              Cast<AOpenDoorTimelineCurve>              (Hit.              GetActor              (              )              )              ;              }              }              }              else              {              InfoWidget->              GetWidgetFromName              (              "helpimage"              )              ->              SetVisibility              (ESlateVisibility::Hidden)              ;              CurrentDoor              =              NULL              ;              }              }                      

Next, bind the OnAction event in the SetupPlayerInputComponent function.

                          .              .              .              // Bind action event              PlayerInputComponent->              BindAction              (              "Action"              ,              IE_Pressed,              this              ,              &AUnrealCPPCharacter::OnAction)              ;                      

Next, create the OnAction function to run the door's toggle function;

OnAction

                          void              AUnrealCPPCharacter              ::              OnAction              (              )              {              if              (CurrentDoor)              {              CurrentDoor->              ToggleDoor              (              )              ;              }              }                      

Save and compile. Go into the editor, select the character and add the user widget class to them in the details panel. Drag and drop the door actor into the game world. Add the float curve to the actor in the details panel. Add the door frame and and door meshes. Now when you push play the door will open and close the player pushes the Action key while in range.

Below is the final code.

UnrealCpp.Build.cs

                          using              UnrealBuildTool;              public              class              UnrealCPP              :                              ModuleRules                            {              public              UnrealCPP              (ReadOnlyTargetRules Target)              :              base              (Target)              {              PCHUsage              =              PCHUsageMode.UseExplicitOrSharedPCHs;              PublicDependencyModuleNames.              AddRange              (              new              string[              ]              {              "Core"              ,              "CoreUObject"              ,              "Engine"              ,              "InputCore"              ,              "HeadMountedDisplay"              ,              "UMG"              ,              "Slate"              ,              "SlateCore"              }              )              ;              }              }                      

OpenDoorTimelineCurve.h

                                          #                pragma                once                                            #                include                "CoreMinimal.h"                                            #                include                "GameFramework/Actor.h"                                            #                include                "Components/TimelineComponent.h"                                            #                include                "Components/BoxComponent.h"                                            #                include                "OpenDoorTimelineCurve.generated.h"                            UCLASS              (              )              class              UNREALCPP_API              AOpenDoorTimelineCurve              :              public              AActor              {              GENERATED_BODY              (              )              public              :              // Sets default values for this actor's properties              AOpenDoorTimelineCurve              (              )              ;              protected              :              // Called when the game starts or when spawned              virtual              void              BeginPlay              (              )              override;              public              :              // Called every frame              virtual              void              Tick              (              float              DeltaTime)              override;              UPROPERTY              (EditAnywhere)              UStaticMeshComponent*              Door;              UPROPERTY              (EditAnywhere)              UStaticMeshComponent*              DoorFrame;              UPROPERTY              (EditAnywhere)              UCurveFloat              *DoorCurve;              UFUNCTION              (              )              void              ControlDoor              (              )              ;              UFUNCTION              (              )              void              ToggleDoor              (              )              ;              UFUNCTION              (              )              void              SetState              (              )              ;              bool              Open;              bool              ReadyState;              float              RotateValue;              float              CurveFloatValue;              float              TimelineValue;              FRotator DoorRotation;              FTimeline MyTimeline;              }              ;                      

OpenDoorTimelineCurve.cpp

                                          #                include                "OpenDoorTimelineCurve.h"                                            #                include                "Kismet/KismetMathLibrary.h"                            // Sets default values              AOpenDoorTimelineCurve              ::              AOpenDoorTimelineCurve              (              )              {              // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.              PrimaryActorTick.bCanEverTick              =              true              ;              Open              =              false              ;              ReadyState              =              true              ;              DoorFrame              =              CreateDefaultSubobject<UStaticMeshComponent>              (              TEXT              (              "DoorFrame"              )              )              ;              RootComponent              =              DoorFrame;              Door              =              CreateDefaultSubobject<UStaticMeshComponent>              (              TEXT              (              "My Mesh"              )              )              ;              Door->              SetupAttachment              (RootComponent)              ;              }              // Called when the game starts or when spawned              void              AOpenDoorTimelineCurve              ::              BeginPlay              (              )              {              Super              ::              BeginPlay              (              )              ;              RotateValue              =              1.0f              ;              if              (DoorCurve)              {              FOnTimelineFloat TimelineCallback;              FOnTimelineEventStatic TimelineFinishedCallback;              TimelineCallback.              BindUFunction              (              this              ,              FName              (              "ControlDoor"              )              )              ;              TimelineFinishedCallback.              BindUFunction              (              this              ,              FName{              TEXT              (              "SetState"              )              }              )              ;              MyTimeline.              AddInterpFloat              (DoorCurve,              TimelineCallback)              ;              MyTimeline.              SetTimelineFinishedFunc              (TimelineFinishedCallback)              ;              }              }              // Called every frame              void              AOpenDoorTimelineCurve              ::              Tick              (              float              DeltaTime)              {              Super              ::              Tick              (DeltaTime)              ;              MyTimeline.              TickTimeline              (DeltaTime)              ;              }              void              AOpenDoorTimelineCurve              ::              ControlDoor              (              )              {              TimelineValue              =              MyTimeline.              GetPlaybackPosition              (              )              ;              CurveFloatValue              =              RotateValue*DoorCurve->              GetFloatValue              (TimelineValue)              ;              FQuat NewRotation              =              FQuat              (              FRotator              (              0.f              ,              CurveFloatValue,              0.f              )              )              ;              Door->              SetRelativeRotation              (NewRotation)              ;              }              void              AOpenDoorTimelineCurve              ::              SetState              (              )              {              ReadyState              =              true              ;              }              void              AOpenDoorTimelineCurve              ::              ToggleDoor              (              )              {              if              (ReadyState)              {              Open              =              !Open;              // alternative way to get pawn position              // GetWorld()->GetFirstPlayerController()->GetPawn()->GetActorLocation()              APawn*              OurPawn              =              UGameplayStatics              ::              GetPlayerPawn              (              this              ,              0              )              ;              FVector PawnLocation              =              OurPawn->              GetActorLocation              (              )              ;              FVector Direction              =              GetActorLocation              (              )              -              PawnLocation;              Direction              =              UKismetMathLibrary              ::              LessLess_VectorRotator              (Direction,              GetActorRotation              (              )              )              ;              DoorRotation              =              Door->RelativeRotation;              if              (Open)              {              if              (Direction.X              >              0.0f              )              {              RotateValue              =              1.0f              ;              }              else              {              RotateValue              =              -              1.0f              ;              }              ReadyState              =              false              ;              MyTimeline.              PlayFromStart              (              )              ;              }              else              {              ReadyState              =              false              ;              MyTimeline.              Reverse              (              )              ;              }              }              }                      

UnrealCPPCharacter.h

                                          #                include                "CoreMinimal.h"                                            #                include                "GameFramework/Character.h"                                            #                include                "OpenDoorTimelineCurve/OpenDoorTimelineCurve.h"                                            #                include                "Blueprint/UserWidget.h"                                            #                include                "UnrealCPPCharacter.generated.h"                            class              UInputComponent              ;              UCLASS              (config=Game)              class              AUnrealCPPCharacter              :                              public                ACharacter                            {              GENERATED_BODY              (              )              /** Pawn mesh: 1st person view (arms; seen only by self) */              UPROPERTY              (VisibleDefaultsOnly,              Category=Mesh)              class              USkeletalMeshComponent              *              Mesh1P;              /** Gun mesh: 1st person view (seen only by self) */              UPROPERTY              (VisibleDefaultsOnly,              Category              =              Mesh)              class              USkeletalMeshComponent              *              FP_Gun;              /** Location on gun mesh where projectiles should spawn. */              UPROPERTY              (VisibleDefaultsOnly,              Category              =              Mesh)              class              USceneComponent              *              FP_MuzzleLocation;              /** First person camera */              UPROPERTY              (VisibleAnywhere,              BlueprintReadOnly,              Category              =              Camera,              meta              =              (AllowPrivateAccess              =              "true"              )              )              class              UCameraComponent              *              FirstPersonCameraComponent;              public              :              AUnrealCPPCharacter              (              )              ;              protected              :              virtual              void              BeginPlay              (              )              ;              virtual              void              Tick              (              float              DeltaSeconds)              override;              public              :              /** Base turn rate, in deg/sec. Other scaling may affect final turn rate. */              UPROPERTY              (VisibleAnywhere,              BlueprintReadOnly,              Category=Camera)              float              BaseTurnRate;              /** Base look up/down rate, in deg/sec. Other scaling may affect final rate. */              UPROPERTY              (VisibleAnywhere,              BlueprintReadOnly,              Category=Camera)              float              BaseLookUpRate;              /** Gun muzzle's offset from the characters location */              UPROPERTY              (EditAnywhere,              BlueprintReadWrite,              Category=Gameplay)              FVector GunOffset;              /** Projectile class to spawn */              UPROPERTY              (EditDefaultsOnly,              Category=Projectile)              TSubclassOf<              class              AUnrealCPPProjectile              >              ProjectileClass;              /** Sound to play each time we fire */              UPROPERTY              (EditAnywhere,              BlueprintReadWrite,              Category=Gameplay)              class              USoundBase              *              FireSound;              /** AnimMontage to play each time we fire */              UPROPERTY              (EditAnywhere,              BlueprintReadWrite,              Category              =              Gameplay)              class              UAnimMontage              *              FireAnimation;              UPROPERTY              (EditAnywhere)              class              AOpenDoorTimelineCurve              *              CurrentDoor;              // Reference UMG Asset in the Editor              UPROPERTY              (EditAnywhere)              TSubclassOf<              class              UUserWidget              >              HelpWidgetClass;              // UPROPERTY(EditAnywhere)              class              UUserWidget              *              InfoWidget;              protected              :              /** Fires a projectile. */              void              OnFire              (              )              ;              /** Action Function */              void              OnAction              (              )              ;              /** Handles moving forward/backward */              void              MoveForward              (              float              Val)              ;              /** Handles stafing movement, left and right */              void              MoveRight              (              float              Val)              ;              /** 	 * Called via input to turn at a given rate. 	 * @param Rate	This is a normalized rate, i.e. 1.0 means 100% of desired turn rate 	 */              void              TurnAtRate              (              float              Rate)              ;              /** 	 * Called via input to turn look up/down at a given rate. 	 * @param Rate	This is a normalized rate, i.e. 1.0 means 100% of desired turn rate 	 */              void              LookUpAtRate              (              float              Rate)              ;              protected              :              // APawn interface              virtual              void              SetupPlayerInputComponent              (UInputComponent*              InputComponent)              override;              // End of APawn interface              FORCEINLINE              class              USkeletalMeshComponent              *              GetMesh1P              (              )              const              {              return              Mesh1P;              }              /** Returns FirstPersonCameraComponent subobject **/              FORCEINLINE              class              UCameraComponent              *              GetFirstPersonCameraComponent              (              )              const              {              return              FirstPersonCameraComponent;              }              }              ;                      

UnrealCPPCharacter.cpp

                                          #                include                "UnrealCPPCharacter.h"                                            #                include                "UnrealCPPProjectile.h"                                            #                include                "Animation/AnimInstance.h"                                            #                include                "Camera/CameraComponent.h"                                            #                include                "Components/CapsuleComponent.h"                                            #                include                "Components/SphereComponent.h"                                            #                include                "Components/InputComponent.h"                                            #                include                "GameFramework/InputSettings.h"                                            #                include                "HeadMountedDisplayFunctionLibrary.h"                                            #                include                "Kismet/GameplayStatics.h"                                            #                include                "MotionControllerComponent.h"                                            #                include                "DrawDebugHelpers.h"                            DEFINE_LOG_CATEGORY_STATIC              (LogFPChar,              Warning,              All)              ;              //////////////////////////////////////////////////////////////////////////              // AUnrealCPPCharacter              AUnrealCPPCharacter              ::              AUnrealCPPCharacter              (              )              {              // Set size for collision capsule              GetCapsuleComponent              (              )              ->              InitCapsuleSize              (              55.f              ,              96.0f              )              ;              // set our turn rates for input              BaseTurnRate              =              45.f              ;              BaseLookUpRate              =              45.f              ;              // Create a CameraComponent                            FirstPersonCameraComponent              =              CreateDefaultSubobject<UCameraComponent>              (              TEXT              (              "FirstPersonCamera"              )              )              ;              FirstPersonCameraComponent->              SetupAttachment              (              GetCapsuleComponent              (              )              )              ;              FirstPersonCameraComponent->RelativeLocation              =              FVector              (              -              39.56f              ,              1.75f              ,              64.f              )              ;              // Position the camera              FirstPersonCameraComponent->bUsePawnControlRotation              =              true              ;              // Create a mesh component that will be used when being viewed from a '1st person' view (when controlling this pawn)              Mesh1P              =              CreateDefaultSubobject<USkeletalMeshComponent>              (              TEXT              (              "CharacterMesh1P"              )              )              ;              Mesh1P->              SetOnlyOwnerSee              (              true              )              ;              Mesh1P->              SetupAttachment              (FirstPersonCameraComponent)              ;              Mesh1P->bCastDynamicShadow              =              false              ;              Mesh1P->CastShadow              =              false              ;              Mesh1P->RelativeRotation              =              FRotator              (              1.9f              ,              -              19.19f              ,              5.2f              )              ;              Mesh1P->RelativeLocation              =              FVector              (              -              0.5f              ,              -              4.4f              ,              -              155.7f              )              ;              // Create a gun mesh component              FP_Gun              =              CreateDefaultSubobject<USkeletalMeshComponent>              (              TEXT              (              "FP_Gun"              )              )              ;              FP_Gun->              SetOnlyOwnerSee              (              true              )              ;              // only the owning player will see this mesh              FP_Gun->bCastDynamicShadow              =              false              ;              FP_Gun->CastShadow              =              false              ;              // FP_Gun->SetupAttachment(Mesh1P, TEXT("GripPoint"));              FP_Gun->              SetupAttachment              (RootComponent)              ;              FP_MuzzleLocation              =              CreateDefaultSubobject<USceneComponent>              (              TEXT              (              "MuzzleLocation"              )              )              ;              FP_MuzzleLocation->              SetupAttachment              (FP_Gun)              ;              FP_MuzzleLocation->              SetRelativeLocation              (              FVector              (              0.2f              ,              48.4f              ,              -              10.6f              )              )              ;              // Default offset from the character location for projectiles to spawn              GunOffset              =              FVector              (              100.0f              ,              0.0f              ,              10.0f              )              ;              // Note: The ProjectileClass and the skeletal mesh/anim blueprints for Mesh1P, FP_Gun, and VR_Gun                            // are set in the derived blueprint asset named MyCharacter to avoid direct content references in C++.              CurrentDoor              =              NULL              ;              }              void              AUnrealCPPCharacter              ::              BeginPlay              (              )              {              // Call the base class                            Super:                              :                BeginPlay                (                )                            ;              //Attach gun mesh component to Skeleton, doing it here because the skeleton is not yet created in the constructor              FP_Gun->              AttachToComponent              (Mesh1P,              FAttachmentTransformRules              (EAttachmentRule::SnapToTarget,              true              )              ,              TEXT              (              "GripPoint"              )              )              ;              Mesh1P->              SetHiddenInGame              (              false              ,              true              )              ;              if              (HelpWidgetClass)              {              InfoWidget              =              CreateWidget<UUserWidget>              (              GetWorld              (              )              ,              HelpWidgetClass)              ;              if              (InfoWidget)              {              InfoWidget->              AddToViewport              (              )              ;              }              }              }              //Called every frame              void              AUnrealCPPCharacter              ::              Tick              (              float              DeltaTime)              {              Super              ::              Tick              (DeltaTime)              ;              FHitResult Hit;              FVector Start              =              FirstPersonCameraComponent->              GetComponentLocation              (              )              ;              FVector ForwardVector              =              FirstPersonCameraComponent->              GetForwardVector              (              )              ;              FVector End              =              (              (ForwardVector              *              200.f              )              +              Start)              ;              FCollisionQueryParams CollisionParams;              DrawDebugLine              (              GetWorld              (              )              ,              Start,              End,              FColor::Green,              false              ,              1              ,              0              ,              1              )              ;              if              (              GetWorld              (              )              ->              LineTraceSingleByChannel              (Hit,              Start,              End,              ECC_Visibility,              CollisionParams)              )              {              if              (Hit.bBlockingHit)              {              if              (Hit.              GetActor              (              )              ->              GetClass              (              )              ->              IsChildOf              (              AOpenDoorTimelineCurve              ::              StaticClass              (              )              )              )              {              InfoWidget->              GetWidgetFromName              (              "helpimage"              )              ->              SetVisibility              (ESlateVisibility::Visible)              ;              CurrentDoor              =              Cast<AOpenDoorTimelineCurve>              (Hit.              GetActor              (              )              )              ;              }              }              }              else              {              InfoWidget->              GetWidgetFromName              (              "helpimage"              )              ->              SetVisibility              (ESlateVisibility::Hidden)              ;              CurrentDoor              =              NULL              ;              }              }              //////////////////////////////////////////////////////////////////////////              // Input              void              AUnrealCPPCharacter              ::              SetupPlayerInputComponent              (              class              UInputComponent              *              PlayerInputComponent)              {              // set up gameplay key bindings              check              (PlayerInputComponent)              ;              // Bind jump events              PlayerInputComponent->              BindAction              (              "Jump"              ,              IE_Pressed,              this              ,              &ACharacter::Jump)              ;              PlayerInputComponent->              BindAction              (              "Jump"              ,              IE_Released,              this              ,              &ACharacter::StopJumping)              ;              // Bind fire event              PlayerInputComponent->              BindAction              (              "Fire"              ,              IE_Pressed,              this              ,              &AUnrealCPPCharacter::OnFire)              ;              // Bind action event              PlayerInputComponent->              BindAction              (              "Action"              ,              IE_Pressed,              this              ,              &AUnrealCPPCharacter::OnAction)              ;              // Bind movement events              PlayerInputComponent->              BindAxis              (              "MoveForward"              ,              this              ,              &AUnrealCPPCharacter::MoveForward)              ;              PlayerInputComponent->              BindAxis              (              "MoveRight"              ,              this              ,              &AUnrealCPPCharacter::MoveRight)              ;              // We have 2 versions of the rotation bindings to handle different kinds of devices differently              // "turn" handles devices that provide an absolute delta, such as a mouse.              // "turnrate" is for devices that we choose to treat as a rate of change, such as an analog joystick              PlayerInputComponent->              BindAxis              (              "Turn"              ,              this              ,              &APawn::AddControllerYawInput)              ;              PlayerInputComponent->              BindAxis              (              "TurnRate"              ,              this              ,              &AUnrealCPPCharacter::TurnAtRate)              ;              PlayerInputComponent->              BindAxis              (              "LookUp"              ,              this              ,              &APawn::AddControllerPitchInput)              ;              PlayerInputComponent->              BindAxis              (              "LookUpRate"              ,              this              ,              &AUnrealCPPCharacter::LookUpAtRate)              ;              }              void              AUnrealCPPCharacter              ::              OnFire              (              )              {              // try and fire a projectile              if              (ProjectileClass              !=              NULL              )              {              UWorld*              const              World              =              GetWorld              (              )              ;              if              (World              !=              NULL              )              {              const              FRotator SpawnRotation              =              GetControlRotation              (              )              ;              // MuzzleOffset is in camera space, so transform it to world space before offsetting from the character location to find the final muzzle position              const              FVector SpawnLocation              =              (              (FP_MuzzleLocation              !=              nullptr              )              ?              FP_MuzzleLocation->              GetComponentLocation              (              )              :              GetActorLocation              (              )              )              +              SpawnRotation.              RotateVector              (GunOffset)              ;              //Set Spawn Collision Handling Override              FActorSpawnParameters ActorSpawnParams;              ActorSpawnParams.SpawnCollisionHandlingOverride              =              ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButDontSpawnIfColliding;              // spawn the projectile at the muzzle              World->SpawnActor<AUnrealCPPProjectile>              (ProjectileClass,              SpawnLocation,              SpawnRotation,              ActorSpawnParams)              ;              }              }              // try and play the sound if specified              if              (FireSound              !=              NULL              )              {              UGameplayStatics              ::              PlaySoundAtLocation              (              this              ,              FireSound,              GetActorLocation              (              )              )              ;              }              // try and play a firing animation if specified              if              (FireAnimation              !=              NULL              )              {              // Get the animation object for the arms mesh              UAnimInstance*              AnimInstance              =              Mesh1P->              GetAnimInstance              (              )              ;              if              (AnimInstance              !=              NULL              )              {              AnimInstance->              Montage_Play              (FireAnimation,              1.f              )              ;              }              }              }              void              AUnrealCPPCharacter              ::              MoveForward              (              float              Value)              {              if              (Value              !=              0.0f              )              {              // add movement in that direction              AddMovementInput              (              GetActorForwardVector              (              )              ,              Value)              ;              }              }              void              AUnrealCPPCharacter              ::              MoveRight              (              float              Value)              {              if              (Value              !=              0.0f              )              {              // add movement in that direction              AddMovementInput              (              GetActorRightVector              (              )              ,              Value)              ;              }              }              void              AUnrealCPPCharacter              ::              TurnAtRate              (              float              Rate)              {              // calculate delta for this frame from the rate information              AddControllerYawInput              (Rate              *              BaseTurnRate              *              GetWorld              (              )              ->              GetDeltaSeconds              (              )              )              ;              }              void              AUnrealCPPCharacter              ::              LookUpAtRate              (              float              Rate)              {              // calculate delta for this frame from the rate information              AddControllerPitchInput              (Rate              *              BaseLookUpRate              *              GetWorld              (              )              ->              GetDeltaSeconds              (              )              )              ;              }              void              AUnrealCPPCharacter              ::              OnAction              (              )              {              if              (CurrentDoor)              {              CurrentDoor->              ToggleDoor              (              )              ;              }              }                      

Object Move Back and Forth on Timeline Ue4

Source: https://unrealcpp.com/open-door-with-timeline/

0 Response to "Object Move Back and Forth on Timeline Ue4"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel