1. Input 구성
Project Setting -> Input 으로 가면 Binding 그룹을 볼 수 있습니다.
여기에 액션 매핑(Action Mappings), 축 매핑(Axis Mappings)을 볼 수 있는데 각 기능은 아래와 같습니다.
- 액션 매핑(Action Mappings)
- 키를 누르고 떼는 것
- 트리거 같은 개념(클릭 시, 무엇을 해라)
- Ex) Space Bar클릭 시, 점프
- 축 매핑(Axis Mappings)
- 연속된 범위의 입력에 대해서 매핑
- 스케일 값을 지정할 수 있다.
- Ex) W, A, S, D를 통해 캐릭터 움직이기
우리는 캐릭터 움직임을 구현할 것이기 때문에 축 매핑을 사용할 것이고 아래와 같이 세팅해 보겠습니다.
- MoveFoward은 W가 전방이기에 스케일 1.0 / 반대인 S는 스케일 -1.0
- MoveRight는 D가 전방(우측)이기 때문에 스케일 1.0 / 반대인 A는 스케일 -1.0
2. 코드
header 파일부터 확인해 보자
- _speed: 캐릭터의 이동 속도를 조절해 주는 변수
- void MoveFoward(float): Axis Mappings에 추가한 MoveFoward와 연결되는 메서드
- void MoveRight(float): Axis Mappings에 추가한 MoveRight와 연결되는 메서드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// .h 파일
UCLASS()
class TPS_PROTOTYPE_API APlayerCharacter : public ACharacter
{
GENERATED_BODY()
private:
UPROPERTY(EditAnywhere, meta = (AllowPrivateAccess = "true"))
float _speed = 1.0f;
protected:
void MoveForward(float); // MoveFoward 메소드
void MoveRight(float); // MoveRight 메소드
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
}
UInputComponent의 BindAxis를 통해서 Axis Mappings와 메서드를 묶어주자
1
2
3
4
5
6
7
8
// Called to bind functionality to input
void APlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
PlayerInputComponent->BindAxis("MoveForward", this, &APlayerCharacter::MoveForward);
PlayerInputComponent->BindAxis("MoveRight", this, &APlayerCharacter::MoveRight);
}
2-1. void MoveFoward(float) 정의부
1
2
3
4
5
6
void APlayerCharacter::MoveForward(float AxisValue)
{
const FVector direction = FRotationMatrix(Controller->GetControlRotation()).GetUnitAxis(EAxis::X);
AddMovementInput(direction, FMath::Clamp(AxisValue * _speed, -1.f * _speed, 1.f * _speed));
}
2-2. void MoveRight(float) 정의부
1
2
3
4
5
6
void APlayerCharacter::MoveRight(float AxisValue)
{
const FVector direction = FRotationMatrix(Controller->GetControlRotation()).GetUnitAxis(EAxis::Y);
AddMovementInput(direction, FMath::Clamp(AxisValue * _speed, -1.f * _speed, 1.f * _speed));
}
2-3. FRotationMatrix란?
FRotationMatrix에 대한 자세한 내용이 적힌 글을 보지 못해서 나름대로 고민을 해보았는데
FRotationMatrix의 파라미터를 통해 Controller->GetControlRotation()을 전달하는 것으로 보아
FRotationMatrix는 전달된 값을 회전행렬값으로 바꿔주는 것으로 이해했습니다.
그렇기 때문에 GetUnitAxis(EAxis::)를 통해서 원하는 축의 단위 벡터를 구할 수 있고
이 벡터는 당연히 캐릭터의 방향벡터가 되는 것입니다.
2-4. AddMovementInput
FRotationMatrix를 통해 얻은 방향벡터를 기반으로 AddMovementInput으로 캐릭터 이동을 시켜주었다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
virtual void AddMovementInput
(
/**
* Direction in world space to apply input
*/
FVector WorldDirection,
/**
* Scale to apply to input.
* This can be used for analog input, ie a value of 0.5 applies half the normal value,
* while -1.0 would reverse the direction.
*/
float ScaleValue,
/**
* If true always add the input, ignoring the result of IsMoveInputIgnored().
*/
bool bForce
)