-
[Unreal Engine] CounterStrike류 멀티플레이 게임 제작 2# 캐릭터 이동2024년 04월 07일
- 유니얼
-
작성자
-
2024.04.07.:54
728x90개요
언리얼 엔진을 통해서 CounterStrike류의 멀티플레이 게임 제작 과정을 담은 블로그입니다. 게임을 제작하는 데 있어 플레이어의 입력과 캐릭터의 움직임은 게임 플레이의 핵심 요소입니다. 이번 글에서는 Unreal Engine의 EnhancedInput 시스템을 활용하여 3인칭 캐릭터의 움직임을 어떻게 구현할 수 있는지 탐구해보겠습니다.
EnhancedInput 내용
EnhancedInput은 Unreal Engine에서 제공하는 새로운 입력 시스템으로, 개발자들에게 보다 세밀하고 유연한 입력 처리 방법을 제공합니다. 기존의 Input 시스템보다 다양한 기능을 지원하며, 특히 멀티플레이 게임에서의 복잡한 입력 요구 사항을 효과적으로 처리할 수 있습니다.
EnhancedInput 시스템의 주요 특징은 다음과 같습니다:
- 컨텍스트 기반 입력 처리: 플레이어의 현재 상태나 게임 환경에 따라 다르게 입력을 처리할 수 있습니다.
- 입력 매핑의 유연성: 같은 행동에 대해 다양한 입력을 매핑할 수 있으며, 이를 통해 사용자 정의 컨트롤 설정을 용이하게 합니다.
- 입력 이벤트의 세분화: 단순한 버튼 누름뿐만 아니라, 버튼의 누름 강도나 지속 시간 같은 세부 정보를 처리할 수 있습니다.
구현 방법
설정 단계
EnhancedInput을 사용하기 전에, 먼저 프로젝트 설정에서 Enhanced Input Plugin을 활성화해야 합니다. 이는 Edit > Plugins 메뉴에서 찾을 수 있으며, "Input" 섹션 아래에 위치합니다. C++ 코드에서 EnhancedInput을 사용할려면 Build.cs 스크립트 내에 아래의 "EnhancedInput"을 추가해야 합니다.
// Fill out your copyright notice in the Description page of Project Settings. using UnrealBuildTool; public class CounterStrike : ModuleRules { public CounterStrike(ReadOnlyTargetRules Target) : base(Target) { PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore","EnhancedInput"}); PrivateDependencyModuleNames.AddRange(new string[] { }); // Uncomment if you are using Slate UI // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" }); // Uncomment if you are using online features // PrivateDependencyModuleNames.Add("OnlineSubsystem"); // To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true } }
InputAction 및 Input Mapping Context
EnhancedInput 시스템은 주로 두 가지 주요 구성 요소를 사용합니다: InputAction과 Input Mapping Context.
InputAction
InputAction은 플레이어가 게임 내에서 수행할 수 있는 개별적인 액션을 정의합니다. 예를 들어, "MoveForward", "Jump", "LookAround"과 같은 액션들이 이에 해당합니다. 각 InputAction은 특정 입력(키보드의 키, 마우스 클릭, 게임 패드 버튼 등)에 바인딩되며, 이를 통해 개발자는 다양한 플레이어 입력을 게임 내에서의 구체적인 반응으로 변환할 수 있습니다.
Input Mapping Context
Input Mapping Context는 하나 이상의 InputAction을 그룹화하고, 이들 액션에 대한 구체적인 입력 바인딩을 정의하는 역할을 합니다. Input Mapping Context를 사용하면, 게임의 다양한 상황(예: 보행, 차량 운전, 메뉴 탐색 등)에 따라 다른 입력 설정을 쉽게 적용할 수 있습니다. 이는 게임의 다양한 상황에서 플레이어에게 일관되고 직관적인 입력 경험을 제공하는 데 중요합니다.
C++ 코드
플레이어 입력 컴포넌트 설정
앞서 설정한 InputAction과 Input Mapping Context를 실제 게임 코드에 적용하기 위해서는, 플레이어 캐릭터나 컨트롤러 클래스 내에서 EnhancedInputComponent를 설정하고, 필요한 Input Mapping Context를 활성화해야 합니다.
먼저, 플레이어 캐릭터 클래스의 헤더 파일에서 변수를 선언하는 방법입니다.
protected: void OnMove(const FInputActionValue& value); void OnLook(const FInputActionValue& value); public: UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input", meta = (AllowPrivateAccess = "true")) class UInputMappingContext* InputSystem; UPROPERTY(EditAnywhere,BlueprintReadWrite,Category="Input",meta=(AllowPrivateAccess = "true")) UInputAction* MoveAction; UPROPERTY(EditAnywhere,BlueprintReadWrite,Category="Input",meta=(AllowPrivateAccess = "true")) UInputAction* LookAction; UPROPERTY(EditAnywhere,BlueprintReadWrite,Category="Input",meta=(AllowPrivateAccess = "true")) float MouseHipTurnRate; UPROPERTY(EditAnywhere,BlueprintReadWrite,Category="Input",meta=(AllowPrivateAccess = "true")) float MouseHipLookupRate;
그 다음, 플레이어의 입력 컴포넌트를 설정하는 과정에서 EnhancedInputComponent로 캐스팅하고, 원하는 액션을 바인딩합니다.
// 플레이어 입력 컴포넌트를 설정합니다. void APlayerBase::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) { Super::SetupPlayerInputComponent(PlayerInputComponent); // UEnhancedInputComponent로 캐스팅하여 추가 설정을 합니다. if(UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent)) { // 플레이어의 이동 및 조작을 위한 액션 바인딩을 설정합니다. EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &APlayerBase::OnMove); EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &APlayerBase::OnLook); } }
이 코드는 플레이어의 입력 컴포넌트 설정 과정에서 EnhancedInputComponent를 설정하고, "Move"와 "Look" 액션을 바인딩하는 과정을 보여줍니다.
이동 처리
플레이어의 이동을 처리하는 Move 함수는 입력 값에서 2D 벡터를 추출하고, 이를 기반으로 캐릭터를 이동시킵니다.
// 이동 액션을 처리하는 함수입니다. void APlayerBase::OnMove(const FInputActionValue& value) { FVector2D MovementVector = value.Get<FVector2D>(); if (Controller != nullptr) { AddMovementInput(GetActorForwardVector(), MovementVector.Y); AddMovementInput(GetActorRightVector(), MovementVector.X); } }
이 부분에서는 플레이어의 입력에 따라 캐릭터를 앞뒤로 이동시키거나 좌우로 회전시키는 로직을 구현합니다.
시선 조절 처리
Look 함수는 플레이어의 시선 조절 입력을 처리합니다. 입력 값으로부터 시선 이동을 위한 2D 벡터를 얻어, 캐릭터의 시선을 조절합니다.
// 시선 이동(조준)을 처리하는 함수입니다. void APlayerBase::OnLook(const FInputActionValue& value) { FVector2D LookAxisVector = value.Get<FVector2D>(); if (Controller != nullptr) { AddControllerYawInput(-LookAxisVector.X); AddControllerPitchInput(LookAxisVector.Y); } }
이 함수에서는 마우스 입력을 통해 캐릭터의 시선 방향을 변경하는 로직을 구현합니다.
전체코드
PlayerBase.h
// Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "InputActionValue.h" #include "GameFramework/Character.h" #include "PlayerBase.generated.h" class UInputAction; class USpringArmComponent; class UCameraComponent; UCLASS() class COUNTERSTRIKE_API APlayerBase : public ACharacter { GENERATED_BODY() public: // Sets default values for this character's properties APlayerBase(); protected: // Called when the game starts or when spawned virtual void BeginPlay() override; public: // Called every frame virtual void Tick(float DeltaTime) override; protected: // Called to bind functionality to input virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override; protected: void OnMove(const FInputActionValue& value); void OnLook(const FInputActionValue& value); public: UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input", meta = (AllowPrivateAccess = "true")) class UInputMappingContext* InputSystem; UPROPERTY(EditAnywhere,BlueprintReadWrite,Category="Input",meta=(AllowPrivateAccess = "true")) UInputAction* MoveAction; UPROPERTY(EditAnywhere,BlueprintReadWrite,Category="Input",meta=(AllowPrivateAccess = "true")) UInputAction* LookAction; UPROPERTY(EditAnywhere,BlueprintReadWrite,Category="Input",meta=(AllowPrivateAccess = "true")) float MouseHipTurnRate; UPROPERTY(EditAnywhere,BlueprintReadWrite,Category="Input",meta=(AllowPrivateAccess = "true")) float MouseHipLookupRate; };
PlayerBase.cpp
// Fill out your copyright notice in the Description page of Project Settings. #include "PlayerBase.h" #include "EnhancedInputComponent.h" #include "EnhancedInputSubsystems.h" // Sets default values APlayerBase::APlayerBase() { // 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; bUseControllerRotationPitch = false; bUseControllerRotationYaw = true; bUseControllerRotationRoll = false; } // Called when the game starts or when spawned void APlayerBase::BeginPlay() { Super::BeginPlay(); if(APlayerController* PlayerController = Cast<APlayerController>(Controller)) { if(UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer())) { Subsystem->AddMappingContext(InputSystem,0); } } } // Called every frame void APlayerBase::Tick(float DeltaTime) { Super::Tick(DeltaTime); } // 플레이어 입력 컴포넌트를 설정합니다. void APlayerBase::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) { Super::SetupPlayerInputComponent(PlayerInputComponent); // UEnhancedInputComponent로 캐스팅하여 추가 설정을 합니다. if(UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent)) { // 플레이어의 이동 및 조작을 위한 액션 바인딩을 설정합니다. EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &APlayerBase::OnMove); EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &APlayerBase::OnLook); } } // 이동 액션을 처리하는 함수입니다. void APlayerBase::OnMove(const FInputActionValue& value) { FVector2D MovementVector = value.Get<FVector2D>(); if (Controller != nullptr) { AddMovementInput(GetActorForwardVector(), MovementVector.Y); AddMovementInput(GetActorRightVector(), MovementVector.X); } } // 시선 이동(조준)을 처리하는 함수입니다. void APlayerBase::OnLook(const FInputActionValue& value) { FVector2D LookAxisVector = value.Get<FVector2D>(); if (Controller != nullptr) { AddControllerYawInput(-LookAxisVector.X); AddControllerPitchInput(LookAxisVector.Y); } }
결론
Unreal Engine의 EnhancedInput을 사용하면, 개발자는 플레이어의 입력을 보다 세밀하게 제어할 수 있습니다. 이를 통해 3인칭 캐릭터의 움직임과 시선 조절을 자연스럽고 직관적으로 구현할 수 있으며, 이는 게임의 몰입감을 크게 향상시킬 수 있습니다.
반응형다음글이전글이전 글이 없습니다.댓글