보키_기록용
UE5 Enhanced Input으로 카메라 터치 조작하기(Pan Camera) 본문
Lyra 프로젝트를 보면 LyraHeroComponent에 Input_LookMouse()에 해당되는 마우스로 화면을 움직이는 조작을 모바일 터치조작(Pan)방식으로 하는 방법을 정리한다.
※ Pan 조작이란?
손가락을 댄 후, 손을 떼지 않고 계속적으로 드래그하는 움직임.
Enhanced Input 적용방식 참조 : https://bokki0117.tistory.com/33
C++에서 Enhanced Input System 사용하기
Lyra 게임을 살펴보다가 테스트용으로 Enhanced Input System이라는 것을 적용해보기로 했다. Enhanced Input 핵심 요소 입력 액션(Input Actions) : Enhanced Input System과 프로젝트 코드 사이의 통신 링크. 점프하
bokki0117.tistory.com
위 링크에서 보았듯이, Enhanced Input에서 Input을 추가하려면
- InputAction
- InputMappingContext에 만든 InputAction 설정
- InputConfig에 만든 InputAction 설정
- 실제 코드와 바인딩
과정이 필요하다.
1. InputAction 생성
값 타입을 Axis2D(Vector2D)로 하는 InputAction을 생성한다.
2. InputMappingContext에 만든 InputAction 설정
3.InputConfig에 만든 InputAction 설정
InputConfig에서 설정하기 전에 Enhanced Input은 Tag로 코드와 바인딩하기 때문에 Tag를 생성해야 한다.
GameplayTag 클래스에서 InputTag_PanCamera를 추가한다.
//TestGameplayTag.h
#pragma once
#include "CoreMinimal.h"
#include "GameplayTagContainer.h"
class UGameplayTagsManager;
/**
*
*/
struct DEDISERVERTEST_API FTestGameplayTags : public FNoncopyable
{
public:
static const FTestGameplayTags& Get() { return GameplayTag; }
static void InitializeNativeTags();
FORCEINLINE const FGameplayTag& Move() const { return InputTag_Move; }
FORCEINLINE const FGameplayTag& LookMouse() const { return InputTag_Look_Mouse; }
FORCEINLINE const FGameplayTag& Jump() const { return InputTag_Jump; }
// PanCamera 추가!
FORCEINLINE const FGameplayTag& PanCamera() const { return InputTag_PanCamera; }
protected:
void AddAllTags(UGameplayTagsManager& Manager);
void AddTag(FGameplayTag& OutTag, const ANSICHAR* TagName, const ANSICHAR* TagComment);
private:
//Input Tag
FGameplayTag InputTag_Move;
FGameplayTag InputTag_Look_Mouse;
FGameplayTag InputTag_Jump;
// PanCamera 추가!
FGameplayTag InputTag_PanCamera;
static FTestGameplayTags GameplayTag;
};
//TestGameplayTag.cpp
#include "TestGameplayTag.h"
#include "GameplayTagsManager.h"
#include "Engine/EngineTypes.h"
FTestGameplayTags FTestGameplayTags::GameplayTag;
void FTestGameplayTags::InitializeNativeTags()
{
UGameplayTagsManager& GameplayTagManager = UGameplayTagsManager::Get();
GameplayTag.AddAllTags(GameplayTagManager);
GameplayTagManager.DoneAddingNativeTags();
}
void FTestGameplayTags::AddAllTags(UGameplayTagsManager& Manager)
{
AddTag(InputTag_Move, "InputTag.Move", "Move input.");
AddTag(InputTag_Look_Mouse, "InputTag.Look.Mouse", "Look (Mouse) input");
AddTag(InputTag_Jump, "InputTag.Jump", "Jump input.");
//PanCamera 추가!!
AddTag(InputTag_PanCamera, "InputTag.PanCamera", "Pan Camera input.");
}
void FTestGameplayTags::AddTag(FGameplayTag& OutTag, const ANSICHAR* TagName, const ANSICHAR* TagComment)
{
OutTag = UGameplayTagsManager::Get().AddNativeGameplayTag(FName(TagName), FString(TEXT("(Native) ")) + FString(TagComment));
}
그 후 InputConfig에서 IA_PanCamera를 Tag과 함께 추가한다.
4. 실제 코드와 바인딩
바인딩은 EnhancedInputComponent를 상속받아 만들었던 InputComponent에서
void BindActionByTag(const UTestInputConfig* InputConfig, const FGameplayTag& InputTag, ETriggerEvent TriggerEvent, UserClass* Object, FuncType Func);
해당 함수를 사용하여 바인딩한다.
//DediServerTestCharacter.h
public:
ADediServerTestCharacter();
UPROPERTY(EditDefaultsOnly, Category = "Input")
UTestInputConfig* InputConfig;
protected:
void Input_Move(const FInputActionValue& InputActionValue);
void Input_Look(const FInputActionValue& InputActionValue);
void Input_Jump(const FInputActionValue& InputActionValue);
//Pan Camera
void Input_StartedPanCamera(const FInputActionValue& InputActionValue);
void Input_TriggeredPanCamera(const FInputActionValue& InputActionValue);
protected:
//Pan Camera
FVector2D StartedPan = FVector2D::ZeroVector;
UPROPERTY(EditAnywhere, Category = "DediServerTest|Input")
float PanSpeed = 10.f;
//DediServerTestCharacter.cpp
void ADediServerTestCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
{
UDediServerTestInputComponent* DediServerTestInputComponent = Cast<UDediServerTestInputComponent>(PlayerInputComponent);
check(DediServerTestInputComponent);
const FTestGameplayTags& GameplayTags = FTestGameplayTags::Get();
DediServerTestInputComponent->BindActionByTag(InputConfig, GameplayTags.Move(), ETriggerEvent::Triggered, this, &ADediServerTestCharacter::Input_Move);
DediServerTestInputComponent->BindActionByTag(InputConfig, GameplayTags.LookMouse(), ETriggerEvent::Triggered, this, &ADediServerTestCharacter::Input_Look);
DediServerTestInputComponent->BindActionByTag(InputConfig, GameplayTags.Jump(), ETriggerEvent::Triggered, this, &ADediServerTestCharacter::Input_Jump);
// Pan Camera
DediServerTestInputComponent->BindActionByTag(InputConfig, GameplayTags.PanCamera(), ETriggerEvent::Started, this, &ADediServerTestCharacter::Input_StartedPanCamera);
DediServerTestInputComponent->BindActionByTag(InputConfig, GameplayTags.PanCamera(), ETriggerEvent::Triggered, this, &ADediServerTestCharacter::Input_TriggeredPanCamera);
}
//DediServerTestCharacter.cpp
void ADediServerTestCharacter::Input_StartedPanCamera(const FInputActionValue& InputActionValue)
{
StartedPan = InputActionValue.Get<FVector2D>();
}
void ADediServerTestCharacter::Input_TriggeredPanCamera(const FInputActionValue& InputActionValue)
{
APawn* Pawn = GetPawn<APawn>();
if (Pawn == nullptr)
{
return;
}
if(GetWorld() == nullptr)
{
return;
}
const FVector2D Value = InputActionValue.Get<FVector2D>() - StartedPan;
if (Value.X != 0.0f)
{
Pawn->AddControllerYawInput(Value.X * GetWorld()->DeltaTimeSeconds * PanSpeed);
}
if (Value.Y != 0.0f)
{
Pawn->AddControllerPitchInput(Value.Y * GetWorld()->DeltaTimeSeconds * PanSpeed);
}
StartedPan = InputActionValue.Get<FVector2D>();
}
ETriggerEvent를 Started로 먼저 받아서 시작 지점의 터치 위치를 저장한다음, AddControllerYawInput(), AddControllerPitchInput()으로 카메라를 조정했다.
정리해놓고 보니 별거 없는데 하나의 InputTag에 ETriggerEvent::Started하고 ETriggerEvent::Triggered 2개를 쓴다는 걸 알아내느라 좀 시간이 걸렸던거 같다. 역시 아직 EnhacedInput에 대해 좀 더 공부할 필요가 보인다.
참고
https://www.youtube.com/watch?v=FUqZNylFy-Y
https://www.youtube.com/watch?v=5pnHzapGGak
'언리얼 > Enhanced Input System' 카테고리의 다른 글
Enhanced Input Priority 및 Consume Input에 대해 (0) | 2023.03.23 |
---|---|
Lyra에서 Input Mapping Context 살펴보기 (3) (0) | 2022.10.27 |
Lyra에서 Input Mapping Context 살펴보기 (2) (0) | 2022.10.26 |
Enhanced Input System을 위한 Game Feature 추가하기 (0) | 2022.10.14 |
Lyra에서 Input Mapping Context 살펴보기 (1) (0) | 2022.10.11 |