Шаблона C++ Персонажа от первого лица

Создайте С++ класс Character и назовите его  как вам угодно. В примере ниже – это “MR_FPS” – не забудьте заменить все обращения к классу в случае, если ваше название отличается. Так же, в нашем случае – имя проекта “BUZZ3D_API” – Так же нужно поменять на Ваше. Так же в 20 строке идёт подключение интерфейса к персонажу: “public IMR_Interface” – Можно удалить это объявление.

Заголовочный файл класса (MR_FPS.h)

  1. // Fill out your copyright notice in the Description page of Project Settings.
  2. #pragma once
  3. #include "CoreMinimal.h"
  4. #include "MR_Interface.h"
  5. #include "InputActionValue.h"
  6. #include "GameFramework/Character.h"
  7. #include "DrawDebugHelpers.h"
  8. #include "MR_FPS.generated.h"
  9. class UInputComponent;
  10. class USkeletalMeshComponent;
  11. class USceneComponent;
  12. class UCameraComponent;
  13. class UAnimMontage;
  14. class USoundBase;
  15. UCLASS()
  16. class BUZZ3D_API AMR_FPS : public ACharacter, public IMR_Interface
  17. {
  18. GENERATED_BODY()
  19. UPROPERTY(VisibleDefaultsOnly, Category=Mesh)
  20. USkeletalMeshComponent* Mesh1P;
  21. UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
  22. UCameraComponent* FirstPersonCameraComponent;
  23. UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Input, meta=(AllowPrivateAccess = "true"))
  24. class UInputMappingContext* DefaultMappingContext;
  25. UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Input, meta=(AllowPrivateAccess = "true"))
  26. class UInputAction* JumpAction;
  27. UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
  28. class UInputAction* LookAction;
  29. UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Input, meta=(AllowPrivateAccess = "true"))
  30. class UInputAction* MoveAction;
  31. UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Input, meta=(AllowPrivateAccess = "true"))
  32. class UInputAction* InteractAction;
  33. public:
  34. AMR_FPS();
  35. UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Interact")
  36. FString Focus_Text;
  37. UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Interact")
  38. bool CanMove = true;
  39. protected:
  40. virtual void BeginPlay() override;
  41. void Move(const FInputActionValue& Value);
  42. void Look(const FInputActionValue& Value);
  43. void InteractInput();
  44. void FocusInput();
  45. public:
  46. UFUNCTION(BlueprintCallable)
  47. void Set_Focus_Name(FString Object_Action);
  48. UFUNCTION(BlueprintCallable)
  49. void Clear_Focus_Name();
  50. virtual void Tick(float DeltaTime) override;
  51. virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
  52. USkeletalMeshComponent* GetMesh1P() const { return Mesh1P; }
  53. UCameraComponent* GetFirstPersonCameraComponent() const { return FirstPersonCameraComponent; }
  54. };

У нас реализована настройка управления по новой версии движка (Unreal Engine 5). Так же добавлен UInputAction для интерактивного действия. в CPP файле – мы реализовали line trace  – для фокуса на объекте, и line trace для взаимодействия с объектом по кнопке. Все взаимодействия происходят через интерфейс: IMR_Interface

CPP файл класса (MR_FPS.h)

  1. // Fill out your copyright notice in the Description page of Project Settings.
  2. #include "MR_FPS.h"
  3. #include "Camera/CameraComponent.h"
  4. #include "Components/CapsuleComponent.h"
  5. #include "EnhancedInputComponent.h"
  6. #include "EnhancedInputSubsystems.h"
  7. // Sets default values
  8. AMR_FPS::AMR_FPS()
  9. {
  10. // Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
  11. PrimaryActorTick.bCanEverTick = true;
  12. // Set size for collision capsule
  13. GetCapsuleComponent()->InitCapsuleSize(55.f, 96.0f);
  14. // Create a CameraComponent
  15. FirstPersonCameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("FirstPersonCamera"));
  16. FirstPersonCameraComponent->SetupAttachment(GetCapsuleComponent());
  17. FirstPersonCameraComponent->SetRelativeLocation(FVector(-10.f, 0.f, 60.f)); // Position the camera
  18. FirstPersonCameraComponent->bUsePawnControlRotation = true;
  19. // Create a mesh component that will be used when being viewed from a '1st person' view (when controlling this pawn)
  20. Mesh1P = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("CharacterMesh1P"));
  21. Mesh1P->SetOnlyOwnerSee(true);
  22. Mesh1P->SetupAttachment(FirstPersonCameraComponent);
  23. Mesh1P->bCastDynamicShadow = false;
  24. Mesh1P->CastShadow = false;
  25. //Mesh1P->SetRelativeRotation(FRotator(0.9f, -19.19f, 5.2f));
  26. Mesh1P->SetRelativeLocation(FVector(-30.f, 0.f, -150.f));
  27. }
  28. // Called when the game starts or when spawned
  29. void AMR_FPS::BeginPlay()
  30. {
  31. Super::BeginPlay();
  32. //Add Input Mapping Context
  33. if (APlayerController* PlayerController = Cast<APlayerController>(Controller))
  34. {
  35. if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
  36. {
  37. Subsystem->AddMappingContext(DefaultMappingContext, 0);
  38. }
  39. }
  40. }
  41. void AMR_FPS::Move(const FInputActionValue& Value)
  42. {
  43. // input is a Vector2D
  44. if (!CanMove) return;
  45. FVector2D MovementVector = Value.Get<FVector2D>();
  46. if (Controller != nullptr)
  47. {
  48. // add movement
  49. AddMovementInput(GetActorForwardVector(), MovementVector.Y);
  50. AddMovementInput(GetActorRightVector(), MovementVector.X);
  51. }
  52. }
  53. void AMR_FPS::Look(const FInputActionValue& Value)
  54. {
  55. // input is a Vector2D
  56. FVector2D LookAxisVector = Value.Get<FVector2D>();
  57. if (Controller != nullptr)
  58. {
  59. // add yaw and pitch input to controller
  60. AddControllerYawInput(LookAxisVector.X);
  61. AddControllerPitchInput(LookAxisVector.Y);
  62. }
  63. }
  64. void AMR_FPS::InteractInput()
  65. {
  66. FVector Loc;
  67. FRotator Rot;
  68. FHitResult HitResult;
  69. GetController()->GetPlayerViewPoint(Loc, Rot);
  70. FVector Start = Loc;
  71. FVector End = Start + (Rot.Vector() * 500);
  72. FCollisionQueryParams TraceParams;
  73. //DrawDebugLine(GetWorld(), Start, End, FColor::Green, false, 1, 0, 1);
  74. GetWorld()->LineTraceSingleByChannel(HitResult, Start, End, ECC_Visibility, TraceParams);
  75. AActor* HitActor = HitResult.GetActor();
  76. if(IMR_Interface* InterActor = Cast<IMR_Interface>(HitActor))
  77. {
  78. InterActor->InteractAPI(this);
  79. }
  80. }
  81. void AMR_FPS::FocusInput()
  82. {
  83. FVector Loc;
  84. FRotator Rot;
  85. FHitResult HitResult;
  86. GetController()->GetPlayerViewPoint(Loc, Rot);
  87. FVector Start = Loc;
  88. FVector End = Start + (Rot.Vector() * 500);
  89. FCollisionQueryParams TraceParams;
  90. //DrawDebugLine(GetWorld(), Start, End, FColor::Green, false, 1, 0, 1);
  91. GetWorld()->LineTraceSingleByChannel(HitResult, Start, End, ECC_Visibility, TraceParams);
  92. AActor* HitActor = HitResult.GetActor();
  93. if(IMR_Interface* InterActor = Cast<IMR_Interface>(HitActor))
  94. {
  95. InterActor->FocusAPI(this);
  96. } else
  97. {
  98. Clear_Focus_Name();
  99. }
  100. }
  101. void AMR_FPS::Set_Focus_Name(FString Object_Action)
  102. {
  103. Focus_Text = Object_Action;
  104. }
  105. void AMR_FPS::Clear_Focus_Name()
  106. {
  107. Focus_Text = "";
  108. }
  109. // Called every frame
  110. void AMR_FPS::Tick(float DeltaTime)
  111. {
  112. Super::Tick(DeltaTime);
  113. FocusInput();
  114. }
  115. // Called to bind functionality to input
  116. void AMR_FPS::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
  117. {
  118. // Set up action bindings
  119. if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent))
  120. {
  121. //Jumping
  122. EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Triggered, this, &ACharacter::Jump);
  123. EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Completed, this, &ACharacter::StopJumping);
  124. //Moving
  125. EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AMR_FPS::Move);
  126. //Looking
  127. EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &AMR_FPS::Look);
  128. //Interact
  129. EnhancedInputComponent->BindAction(InteractAction, ETriggerEvent::Completed, this, &AMR_FPS::InteractInput);
  130. }
  131. }

Это базовый шаблон, который можно спокойно брать и использовать под Шутеры, Хорроры и любые игры от 1-го лица. Проекты на С++ отличаются своей сложностью, но позволяют разрабатывать более гибкие и качественные проекты. 

Вы всегда можете обратиться к нашей команде за помощью в разработке, обучению или заказать прототип под ключ. Вступайте в наш telegram канал: