Создайте С++ класс Character и назовите его как вам угодно. В примере ниже – это “MR_FPS” – не забудьте заменить все обращения к классу в случае, если ваше название отличается. Так же, в нашем случае – имя проекта “BUZZ3D_API” – Так же нужно поменять на Ваше. Так же в 20 строке идёт подключение интерфейса к персонажу: “public IMR_Interface” – Можно удалить это объявление.
- // Fill out your copyright notice in the Description page of Project Settings.
- #pragma once
- #include "CoreMinimal.h"
- #include "MR_Interface.h"
- #include "InputActionValue.h"
- #include "GameFramework/Character.h"
- #include "DrawDebugHelpers.h"
- #include "MR_FPS.generated.h"
- class UInputComponent;
- class USkeletalMeshComponent;
- class USceneComponent;
- class UCameraComponent;
- class UAnimMontage;
- class USoundBase;
- UCLASS()
- class BUZZ3D_API AMR_FPS : public ACharacter, public IMR_Interface
- {
- GENERATED_BODY()
- UPROPERTY(VisibleDefaultsOnly, Category=Mesh)
- USkeletalMeshComponent* Mesh1P;
- UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
- UCameraComponent* FirstPersonCameraComponent;
- UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Input, meta=(AllowPrivateAccess = "true"))
- class UInputMappingContext* DefaultMappingContext;
- UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Input, meta=(AllowPrivateAccess = "true"))
- class UInputAction* JumpAction;
- UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
- class UInputAction* LookAction;
- UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Input, meta=(AllowPrivateAccess = "true"))
- class UInputAction* MoveAction;
- UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Input, meta=(AllowPrivateAccess = "true"))
- class UInputAction* InteractAction;
- public:
- AMR_FPS();
- UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Interact")
- FString Focus_Text;
- UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Interact")
- bool CanMove = true;
- protected:
- virtual void BeginPlay() override;
- void Move(const FInputActionValue& Value);
- void Look(const FInputActionValue& Value);
- void InteractInput();
- void FocusInput();
- public:
- UFUNCTION(BlueprintCallable)
- void Set_Focus_Name(FString Object_Action);
- UFUNCTION(BlueprintCallable)
- void Clear_Focus_Name();
- virtual void Tick(float DeltaTime) override;
- virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
- USkeletalMeshComponent* GetMesh1P() const { return Mesh1P; }
- UCameraComponent* GetFirstPersonCameraComponent() const { return FirstPersonCameraComponent; }
- };
У нас реализована настройка управления по новой версии движка (Unreal Engine 5). Так же добавлен UInputAction для интерактивного действия. в CPP файле – мы реализовали line trace – для фокуса на объекте, и line trace для взаимодействия с объектом по кнопке. Все взаимодействия происходят через интерфейс: IMR_Interface
- // Fill out your copyright notice in the Description page of Project Settings.
- #include "MR_FPS.h"
- #include "Camera/CameraComponent.h"
- #include "Components/CapsuleComponent.h"
- #include "EnhancedInputComponent.h"
- #include "EnhancedInputSubsystems.h"
- // Sets default values
- AMR_FPS::AMR_FPS()
- {
- // Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
- PrimaryActorTick.bCanEverTick = true;
- // Set size for collision capsule
- GetCapsuleComponent()->InitCapsuleSize(55.f, 96.0f);
- // Create a CameraComponent
- FirstPersonCameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("FirstPersonCamera"));
- FirstPersonCameraComponent->SetupAttachment(GetCapsuleComponent());
- FirstPersonCameraComponent->SetRelativeLocation(FVector(-10.f, 0.f, 60.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->SetRelativeRotation(FRotator(0.9f, -19.19f, 5.2f));
- Mesh1P->SetRelativeLocation(FVector(-30.f, 0.f, -150.f));
- }
- // Called when the game starts or when spawned
- void AMR_FPS::BeginPlay()
- {
- Super::BeginPlay();
- //Add Input Mapping Context
- if (APlayerController* PlayerController = Cast<APlayerController>(Controller))
- {
- if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
- {
- Subsystem->AddMappingContext(DefaultMappingContext, 0);
- }
- }
- }
- void AMR_FPS::Move(const FInputActionValue& Value)
- {
- // input is a Vector2D
- if (!CanMove) return;
- FVector2D MovementVector = Value.Get<FVector2D>();
- if (Controller != nullptr)
- {
- // add movement
- AddMovementInput(GetActorForwardVector(), MovementVector.Y);
- AddMovementInput(GetActorRightVector(), MovementVector.X);
- }
- }
- void AMR_FPS::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 AMR_FPS::InteractInput()
- {
- FVector Loc;
- FRotator Rot;
- FHitResult HitResult;
- GetController()->GetPlayerViewPoint(Loc, Rot);
- FVector Start = Loc;
- FVector End = Start + (Rot.Vector() * 500);
- FCollisionQueryParams TraceParams;
- //DrawDebugLine(GetWorld(), Start, End, FColor::Green, false, 1, 0, 1);
- GetWorld()->LineTraceSingleByChannel(HitResult, Start, End, ECC_Visibility, TraceParams);
- AActor* HitActor = HitResult.GetActor();
- if(IMR_Interface* InterActor = Cast<IMR_Interface>(HitActor))
- {
- InterActor->InteractAPI(this);
- }
- }
- void AMR_FPS::FocusInput()
- {
- FVector Loc;
- FRotator Rot;
- FHitResult HitResult;
- GetController()->GetPlayerViewPoint(Loc, Rot);
- FVector Start = Loc;
- FVector End = Start + (Rot.Vector() * 500);
- FCollisionQueryParams TraceParams;
- //DrawDebugLine(GetWorld(), Start, End, FColor::Green, false, 1, 0, 1);
- GetWorld()->LineTraceSingleByChannel(HitResult, Start, End, ECC_Visibility, TraceParams);
- AActor* HitActor = HitResult.GetActor();
- if(IMR_Interface* InterActor = Cast<IMR_Interface>(HitActor))
- {
- InterActor->FocusAPI(this);
- } else
- {
- Clear_Focus_Name();
- }
- }
- void AMR_FPS::Set_Focus_Name(FString Object_Action)
- {
- Focus_Text = Object_Action;
- }
- void AMR_FPS::Clear_Focus_Name()
- {
- Focus_Text = "";
- }
- // Called every frame
- void AMR_FPS::Tick(float DeltaTime)
- {
- Super::Tick(DeltaTime);
- FocusInput();
- }
- // Called to bind functionality to input
- void AMR_FPS::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
- {
- // Set up action bindings
- if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent))
- {
- //Jumping
- EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Triggered, this, &ACharacter::Jump);
- EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Completed, this, &ACharacter::StopJumping);
- //Moving
- EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AMR_FPS::Move);
- //Looking
- EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &AMR_FPS::Look);
- //Interact
- EnhancedInputComponent->BindAction(InteractAction, ETriggerEvent::Completed, this, &AMR_FPS::InteractInput);
- }
- }
Это базовый шаблон, который можно спокойно брать и использовать под Шутеры, Хорроры и любые игры от 1-го лица. Проекты на С++ отличаются своей сложностью, но позволяют разрабатывать более гибкие и качественные проекты.
Вы всегда можете обратиться к нашей команде за помощью в разработке, обучению или заказать прототип под ключ. Вступайте в наш telegram канал: