// Copyright Epic Games, Inc. All Rights Reserved. #include "TP_VehicleAdvPawn.h" #include "TP_VehicleAdvWheelFront.h" #include "TP_VehicleAdvWheelRear.h" #include "Components/SkeletalMeshComponent.h" #include "GameFramework/SpringArmComponent.h" #include "Camera/CameraComponent.h" #include "EnhancedInputComponent.h" #include "EnhancedInputSubsystems.h" #include "InputActionValue.h" #include "ChaosWheeledVehicleMovementComponent.h" #define LOCTEXT_NAMESPACE "VehiclePawn" DEFINE_LOG_CATEGORY(LogTemplateVehicle); ATP_VehicleAdvPawn::ATP_VehicleAdvPawn() { // construct the front camera boom FrontSpringArm = CreateDefaultSubobject(TEXT("Front Spring Arm")); FrontSpringArm->SetupAttachment(GetMesh()); FrontSpringArm->TargetArmLength = 0.0f; FrontSpringArm->bDoCollisionTest = false; FrontSpringArm->bEnableCameraRotationLag = true; FrontSpringArm->CameraRotationLagSpeed = 15.0f; FrontSpringArm->SetRelativeLocation(FVector(30.0f, 0.0f, 120.0f)); FrontCamera = CreateDefaultSubobject(TEXT("Front Camera")); FrontCamera->SetupAttachment(FrontSpringArm); FrontCamera->bAutoActivate = false; // construct the back camera boom BackSpringArm = CreateDefaultSubobject(TEXT("Back Spring Arm")); BackSpringArm->SetupAttachment(GetMesh()); BackSpringArm->TargetArmLength = 650.0f; BackSpringArm->SocketOffset.Z = 150.0f; BackSpringArm->bDoCollisionTest = false; BackSpringArm->bInheritPitch = false; BackSpringArm->bInheritRoll = false; BackSpringArm->bEnableCameraRotationLag = true; BackSpringArm->CameraRotationLagSpeed = 2.0f; BackSpringArm->CameraLagMaxDistance = 50.0f; BackCamera = CreateDefaultSubobject(TEXT("Back Camera")); BackCamera->SetupAttachment(BackSpringArm); // Configure the car mesh GetMesh()->SetSimulatePhysics(true); GetMesh()->SetCollisionProfileName(FName("Vehicle")); // get the Chaos Wheeled movement component ChaosVehicleMovement = CastChecked(GetVehicleMovement()); } void ATP_VehicleAdvPawn::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) { Super::SetupPlayerInputComponent(PlayerInputComponent); if (UEnhancedInputComponent* EnhancedInputComponent = Cast(PlayerInputComponent)) { // steering EnhancedInputComponent->BindAction(SteeringAction, ETriggerEvent::Triggered, this, &ATP_VehicleAdvPawn::Steering); EnhancedInputComponent->BindAction(SteeringAction, ETriggerEvent::Completed, this, &ATP_VehicleAdvPawn::Steering); // throttle EnhancedInputComponent->BindAction(ThrottleAction, ETriggerEvent::Triggered, this, &ATP_VehicleAdvPawn::Throttle); EnhancedInputComponent->BindAction(ThrottleAction, ETriggerEvent::Completed, this, &ATP_VehicleAdvPawn::Throttle); // break EnhancedInputComponent->BindAction(BrakeAction, ETriggerEvent::Triggered, this, &ATP_VehicleAdvPawn::Brake); EnhancedInputComponent->BindAction(BrakeAction, ETriggerEvent::Started, this, &ATP_VehicleAdvPawn::StartBrake); EnhancedInputComponent->BindAction(BrakeAction, ETriggerEvent::Completed, this, &ATP_VehicleAdvPawn::StopBrake); // handbrake EnhancedInputComponent->BindAction(HandbrakeAction, ETriggerEvent::Started, this, &ATP_VehicleAdvPawn::StartHandbrake); EnhancedInputComponent->BindAction(HandbrakeAction, ETriggerEvent::Completed, this, &ATP_VehicleAdvPawn::StopHandbrake); // look around EnhancedInputComponent->BindAction(LookAroundAction, ETriggerEvent::Triggered, this, &ATP_VehicleAdvPawn::LookAround); // toggle camera EnhancedInputComponent->BindAction(ToggleCameraAction, ETriggerEvent::Triggered, this, &ATP_VehicleAdvPawn::ToggleCamera); // reset the vehicle EnhancedInputComponent->BindAction(ResetVehicleAction, ETriggerEvent::Triggered, this, &ATP_VehicleAdvPawn::ResetVehicle); } else { UE_LOG(LogTemplateVehicle, Error, TEXT("'%s' Failed to find an Enhanced Input component! This template is built to use the Enhanced Input system. If you intend to use the legacy system, then you will need to update this C++ file."), *GetNameSafe(this)); } } void ATP_VehicleAdvPawn::Tick(float Delta) { Super::Tick(Delta); // add some angular damping if the vehicle is in midair bool bMovingOnGround = ChaosVehicleMovement->IsMovingOnGround(); GetMesh()->SetAngularDamping(bMovingOnGround ? 0.0f : 3.0f); // realign the camera yaw to face front float CameraYaw = BackSpringArm->GetRelativeRotation().Yaw; CameraYaw = FMath::FInterpTo(CameraYaw, 0.0f, Delta, 1.0f); BackSpringArm->SetRelativeRotation(FRotator(0.0f, CameraYaw, 0.0f)); } void ATP_VehicleAdvPawn::Steering(const FInputActionValue& Value) { // get the input magnitude for steering float SteeringValue = Value.Get(); // add the input ChaosVehicleMovement->SetSteeringInput(SteeringValue); } void ATP_VehicleAdvPawn::Throttle(const FInputActionValue& Value) { // get the input magnitude for the throttle float ThrottleValue = Value.Get(); // add the input ChaosVehicleMovement->SetThrottleInput(ThrottleValue); } void ATP_VehicleAdvPawn::Brake(const FInputActionValue& Value) { // get the input magnitude for the brakes float BreakValue = Value.Get(); // add the input ChaosVehicleMovement->SetBrakeInput(BreakValue); } void ATP_VehicleAdvPawn::StartBrake(const FInputActionValue& Value) { // call the Blueprint hook for the break lights BrakeLights(true); } void ATP_VehicleAdvPawn::StopBrake(const FInputActionValue& Value) { // call the Blueprint hook for the break lights BrakeLights(false); // reset brake input to zero ChaosVehicleMovement->SetBrakeInput(0.0f); } void ATP_VehicleAdvPawn::StartHandbrake(const FInputActionValue& Value) { // add the input ChaosVehicleMovement->SetHandbrakeInput(true); // call the Blueprint hook for the break lights BrakeLights(true); } void ATP_VehicleAdvPawn::StopHandbrake(const FInputActionValue& Value) { // add the input ChaosVehicleMovement->SetHandbrakeInput(false); // call the Blueprint hook for the break lights BrakeLights(false); } void ATP_VehicleAdvPawn::LookAround(const FInputActionValue& Value) { // get the flat angle value for the input float LookValue = Value.Get(); // add the input BackSpringArm->AddLocalRotation(FRotator(0.0f, LookValue, 0.0f)); } void ATP_VehicleAdvPawn::ToggleCamera(const FInputActionValue& Value) { // toggle the active camera flag bFrontCameraActive = !bFrontCameraActive; FrontCamera->SetActive(bFrontCameraActive); BackCamera->SetActive(!bFrontCameraActive); } void ATP_VehicleAdvPawn::ResetVehicle(const FInputActionValue& Value) { // reset to a location slightly above our current one FVector ResetLocation = GetActorLocation() + FVector(0.0f, 0.0f, 50.0f); // reset to our yaw. Ignore pitch and roll FRotator ResetRotation = GetActorRotation(); ResetRotation.Pitch = 0.0f; ResetRotation.Roll = 0.0f; // teleport the actor to the reset spot and reset physics SetActorTransform(FTransform(ResetRotation, ResetLocation, FVector::OneVector), false, nullptr, ETeleportType::TeleportPhysics); GetMesh()->SetPhysicsAngularVelocityInDegrees(FVector::ZeroVector); GetMesh()->SetPhysicsLinearVelocity(FVector::ZeroVector); UE_LOG(LogTemplateVehicle, Error, TEXT("Reset Vehicle")); } #undef LOCTEXT_NAMESPACE