UE5--016--C005DodgeballCharacter--DodgeballPlayerController
1. C005DodgeballCharacter
1.1 C005DodgeballCharacter.h
#pragma once #include "CoreMinimal.h" #include "GameFramework/Character.h" #include "Logging/LogMacros.h" #include "HealthInterface.h" #include "C005DodgeballCharacter.generated.h" class USpringArmComponent; class UCameraComponent; class UInputMappingContext; class UInputAction; struct FInputActionValue; DECLARE_LOG_CATEGORY_EXTERN(LogTemplateCharacter, Log, All); UCLASS(config=Game) class AC005DodgeballCharacter : public ACharacter, public IHealthInterface { GENERATED_BODY() /** Camera boom positioning the camera behind the character */ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true")) USpringArmComponent* CameraBoom; /** Follow camera */ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true")) UCameraComponent* FollowCamera; /** MappingContext */ UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true")) UInputMappingContext* DefaultMappingContext; /** Jump Input Action */ UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true")) UInputAction* JumpAction; /** Move Input Action */ UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true")) UInputAction* MoveAction; /** Look Input Action */ UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true")) UInputAction* LookAction; private: class UHealthComponent* HealthComponent; public: AC005DodgeballCharacter(); protected: /** Called for movement input */ void Move(const FInputActionValue& Value); /** Called for looking input */ void Look(const FInputActionValue& Value); protected: // APawn interface virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override; // To add mapping context virtual void BeginPlay(); public: /** Returns CameraBoom subobject **/ FORCEINLINE class USpringArmComponent* GetCameraBoom() const { return CameraBoom; } /** Returns FollowCamera subobject **/ FORCEINLINE class UCameraComponent* GetFollowCamera() const { return FollowCamera; } // virtual void OnDeath_Implementation() override; virtual void OnTakeDamage_Implementation() override; };
1.2 C005DodgeballCharacter.cpp
#include "C005DodgeballCharacter.h" #include "Engine/LocalPlayer.h" #include "Camera/CameraComponent.h" #include "Components/CapsuleComponent.h" #include "GameFramework/CharacterMovementComponent.h" #include "GameFramework/SpringArmComponent.h" #include "GameFramework/Controller.h" #include "EnhancedInputComponent.h" #include "EnhancedInputSubsystems.h" #include "InputActionValue.h" #include "HealthComponent.h" #include "Kismet/KismetSystemLibrary.h" #include "DodgeballPlayerController.h" DEFINE_LOG_CATEGORY(LogTemplateCharacter); ////////////////////////////////////////////////////////////////////////// // AC005DodgeballCharacter AC005DodgeballCharacter::AC005DodgeballCharacter() { // Set size for collision capsule GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f); // Don't rotate when the controller rotates. Let that just affect the camera. bUseControllerRotationPitch = false; bUseControllerRotationYaw = false; bUseControllerRotationRoll = false; // Configure character movement GetCharacterMovement()->bOrientRotationToMovement = true; // Character moves in the direction of input... GetCharacterMovement()->RotationRate = FRotator(0.0f, 500.0f, 0.0f); // ...at this rotation rate // Note: For faster iteration times these variables, and many more, can be tweaked in the Character Blueprint // instead of recompiling to adjust them GetCharacterMovement()->JumpZVelocity = 700.f; GetCharacterMovement()->AirControl = 0.35f; GetCharacterMovement()->MaxWalkSpeed = 500.f; GetCharacterMovement()->MinAnalogWalkSpeed = 20.f; GetCharacterMovement()->BrakingDecelerationWalking = 2000.f; GetCharacterMovement()->BrakingDecelerationFalling = 1500.0f; // Create a camera boom (pulls in towards the player if there is a collision) CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom")); CameraBoom->SetupAttachment(RootComponent); //CameraBoom->TargetArmLength = 400.0f; // The camera follows at this distance behind the character // The camera follows at this distance behind the character CameraBoom->TargetArmLength = 900.0f; //CameraBoom->bUsePawnControlRotation = true; // Rotate the arm based on the controller //The camera looks down at the player CameraBoom->SetRelativeRotation(FRotator(-70.f, 0.f, 0.f)); // Don't rotate the arm based on the controller CameraBoom->bUsePawnControlRotation = false; // Ignore pawn's pitch, yaw and roll CameraBoom->bInheritPitch = false; CameraBoom->bInheritYaw = false; CameraBoom->bInheritRoll = false; // Create a follow camera FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera")); FollowCamera->SetupAttachment(CameraBoom, USpringArmComponent::SocketName); // Attach the camera to the end of the boom and let the boom adjust to match the controller orientation FollowCamera->bUsePawnControlRotation = false; // Camera does not rotate relative to arm // HealthComponent = CreateDefaultSubobject<UHealthComponent>(TEXT("HealthComponent")); // Note: The skeletal mesh and anim blueprint references on the Mesh component (inherited from Character) // are set in the derived blueprint asset named ThirdPersonCharacter (to avoid direct content references in C++) } void AC005DodgeballCharacter::BeginPlay() { // Call the base class Super::BeginPlay(); } ////////////////////////////////////////////////////////////////////////// // Input void AC005DodgeballCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) { // Add Input Mapping Context if (APlayerController* PlayerController = Cast<APlayerController>(GetController())) { if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer())) { Subsystem->AddMappingContext(DefaultMappingContext, 0); } } // Set up action bindings if (UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(PlayerInputComponent)) { // Jumping EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Started, this, &ACharacter::Jump); EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Completed, this, &ACharacter::StopJumping); // Moving EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AC005DodgeballCharacter::Move); // Looking EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &AC005DodgeballCharacter::Look); } else { UE_LOG(LogTemplateCharacter, Error, TEXT("'%s' Failed to find an Enhanced Input component! "), *GetNameSafe(this)); } } void AC005DodgeballCharacter::Move(const FInputActionValue& Value) { // input is a Vector2D FVector2D MovementVector = Value.Get<FVector2D>(); if (Controller != nullptr) { // find out which way is forward const FRotator Rotation = Controller->GetControlRotation(); const FRotator YawRotation(0, Rotation.Yaw, 0); // get forward vector const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X); // get right vector const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y); // add movement AddMovementInput(ForwardDirection, MovementVector.Y); AddMovementInput(RightDirection, MovementVector.X); } } void AC005DodgeballCharacter::Look(const FInputActionValue& Value) { // input is a Vector2D FVector2D LookAxisVector = Value.Get<FVector2D>(); if (Controller != nullptr) { // add yaw and pitch input to controller AddControllerYawInput(LookAxisVector.X); AddControllerPitchInput(LookAxisVector.Y); } } void AC005DodgeballCharacter::OnDeath_Implementation() { if (1 == 0) { UKismetSystemLibrary::QuitGame(this, nullptr, EQuitPreference::Quit, true); } else { ADodgeballPlayerController* PlayerController = Cast<ADodgeballPlayerController>(GetController()); if (PlayerController != nullptr) { PlayerController->ShowRestartWidget(); } } } void AC005DodgeballCharacter::OnTakeDamage_Implementation() { ADodgeballPlayerController* PlayerController = Cast<ADodgeballPlayerController>(GetController()); if (PlayerController != nullptr) { PlayerController->UpdateHealthPercent(HealthComponent->GetHealthPercent()); } }
1.3 BP_C005DodgeballCharacter
2. DodgeballPlayerController
2.1 DodgeballPlayerController.h
#pragma once #include "CoreMinimal.h" #include "GameFramework/PlayerController.h" #include "DodgeballPlayerController.generated.h" /** * */ UCLASS() class C005DODGEBALL_API ADodgeballPlayerController : public APlayerController { GENERATED_BODY() public: UPROPERTY(EditDefaultsOnly) TSubclassOf<class URestartWidget> BP_RestartWidget; UPROPERTY(EditDefaultsOnly) TSubclassOf<class UHUDWidget> BP_HUDWidget; private: UPROPERTY() class URestartWidget* RestartWidget; UPROPERTY() class UHUDWidget* HUDWidget; public: void ShowRestartWidget(); void HideRestartWidget(); void UpdateHealthPercent(float HealthPercent); protected: virtual void BeginPlay() override; };
2.2 DodgeballPlayerController.cpp
#include "DodgeballPlayerController.h" #include "RestartWidget.h" #include "HUDWidget.h" void ADodgeballPlayerController::ShowRestartWidget() { if (BP_RestartWidget != nullptr) { SetPause(true); SetInputMode(FInputModeUIOnly()); bShowMouseCursor = true; RestartWidget = CreateWidget<URestartWidget>(this, BP_RestartWidget); RestartWidget->AddToViewport(); } } void ADodgeballPlayerController::HideRestartWidget() { RestartWidget->RemoveFromParent(); RestartWidget->Destruct(); SetPause(false); SetInputMode(FInputModeGameOnly()); bShowMouseCursor = false; } void ADodgeballPlayerController::BeginPlay() { Super::BeginPlay(); if (BP_HUDWidget != nullptr) { HUDWidget = CreateWidget<UHUDWidget>(this, BP_HUDWidget); HUDWidget->AddToViewport(); } } void ADodgeballPlayerController::UpdateHealthPercent(float HealthPercent) { if (HUDWidget != nullptr) { HUDWidget->UpdateHealthPercent(HealthPercent); } }
2.3 BP_DodgeballPlayerController