캐릭터 무브먼트 설정

이 튜토리얼에서는 다양한 형태의 캐릭터 무브먼트(Character Movement)를 보여주는 플레이 가능 캐릭터를 생성하는 방법을 알아봅니다.

Choose your operating system:

Windows

macOS

Linux

캐릭터 무브먼트(Character Movement)는 인간형 캐릭터가 월드를 돌아다닐 수 있는 로코모션 시스템을 제공합니다. 캐릭터 무브먼트 컴포넌트캐릭터(Character) 클래스의 무브먼트 모드를 제공하는 액터 컴포넌트로, 걷기, 낙하, 수영, 날기가 있습니다. 또한 캐릭터 무브먼트 컴포넌트는 강력한 네트워크 게임플레이 통합을 특징으로 하며, 개발자가 커스텀 네트워크 무브먼트를 제작하는 데 유용한 프레임워크를 제공합니다.

언리얼 엔진에서의 네트워크 리플리케이션(Network Replication)에 관한 추가 정보는 네트워크 개요 문서를 참고하세요.

이 하우투 게임플레이 가이드에서는 캐릭터 클래스를 생성하고, 무브먼트 로직과 입력을 스크립팅하고, 캐릭터가 어떤 상태에 있는지 판별하는 데 도움이 되는 애니메이션 블루프린트를 작성한 다음, 해당 애니메이션을 재생합니다.

실행 중인 캐릭터 무브먼트

구현 방법 선택

블루프린트

C++

새 프로젝트 생성

  1. 먼저 에픽게임즈 런처 에 로그인하고 추가(New) > 게임(Games) > 기본(Blank) 을 차례대로 선택한 후 CharacterMovement 라는 프로젝트를 생성합니다.

    새 블루프린트 프로젝트 생성

  2. 캐릭터를 애니메이팅하기 위해 필요한 애니메이션 스타터 팩(Animation Starter Pack)에픽게임즈 마켓플레이스에서 무료로 다운로드할 수 있습니다. 무료(Free) 버튼을 클릭하여 애니메이션 스타터 팩을 다운로드하고 에픽게임즈 라이브러리(Epic Games Library) 에 추가합니다.

    애니메이션 스타터 팩 다운로드

  3. 라이브러리(Library) 에서 애니메이션 스타터 팩(Animation Starter Pack) 을 찾아 프로젝트에 추가(Add to Project) 를 클릭한 다음, 에셋을 추가할 프로젝트 선택(Select the Project to Add Asset to) 메뉴에서 CharacterMovement 프로젝트 파일을 찾아 선택하고 프로젝트에 추가(Add to Project) 를 클릭합니다.

    프로젝트에 애니메이션 스타터 팩 추가

  4. 애니메이션 스타터 팩을 프로젝트에 추가하면 콘텐츠 브라우저(Content Browser) 에 해당 스타터 팩이 표시됩니다.

    콘텐츠 브라우저의 애니메이션 스타터 팩

  1. 먼저 추가(New) > 게임(Games) > 기본(Blank) 을 차례대로 선택한 후 CharacterMovement 라는 C++ 프로젝트를 생성합니다.

    새 C++ 프로젝트

  2. 캐릭터를 애니메이팅하기 위해 필요한 애니메이션 스타터 팩(Animation Starter Pack)에픽게임즈 마켓플레이스에서 무료로 다운로드할 수 있습니다. 무료(Free) 버튼을 클릭하여 애니메이션 스타터 팩을 다운로드하고 에픽게임즈 라이브러리(Epic Games Library) 에 추가합니다.

    애니메이션 스타터 팩 다운로드

  3. 라이브러리(Library) 에서 애니메이션 스타터 팩(Animation Starter Pack) 을 찾아 프로젝트에 추가(Add to Project) 를 클릭한 다음, 에셋을 추가할 프로젝트 선택(Select the Project to Add Asset to) 메뉴에서 CharacterMovement 프로젝트 파일을 찾아 선택하고 프로젝트에 추가(Add to Project) 를 클릭합니다.

    프로젝트에 애니메이션 스타터 팩 추가

  4. 애니메이션 스타터 팩을 프로젝트에 추가하면 콘텐츠 브라우저(Content Browser) 에 해당 스타터 팩이 표시됩니다.

    콘텐츠 브라우저의 애니메이션 스타터 팩

플레이어 캐릭터 생성

플레이어가 캐릭터를 제어하려면 캐릭터(Character) 클래스를 생성해야 합니다. 캐릭터는 캐릭터 무브먼트 컴포넌트(Character Movement Component)와 연동되는 폰(Pawn)으로서 인간형 캐릭터가 월드를 활보할 수 있는 로코모션 시스템을 지원합니다. 캐릭터를 단계적으로 설정하는 방법은 다음과 같습니다.

  1. 추가/임포트(Add/Import) 버튼을 클릭하여 BP_PlayerCharacter 라는 새로운 블루프린트 캐릭터(Character) 클래스를 생성합니다.

    새 블루프린트 캐릭터 클래스 추가

  2. BP_PlayerCharacter 를 더블클릭하여 클래스 디폴트 를 연 다음, 컴포넌트(Components) 탭에서 메시 (CharacterMesh0) 스켈레탈 메시 컴포넌트(Skeletal Mesh Component) 를 선택하고 디테일 패널 로 이동합니다.

    이미지를 클릭하면 확대됩니다.

  3. 메시(Mesh) 카테고리 에서 스켈레탈 메시(Skeletal Mesh) 변수 옆에 있는 드롭다운 화살표를 선택하고 드롭다운 메뉴에서 SK_Mannequin 을 선택합니다.

    스켈레탈 메시 선택

  4. 디테일 패널 에서 트랜스폼(Transform) 카테고리 로 이동하여 메시의 위치(Location)회전(Rotation) 을 (0 , 0 , -90 ) 으로 설정합니다.

    트랜스폼 세팅

  5. 이제 캐릭터의 스켈레탈 메시 가 아래 이미지에 보이는 것처럼 앞쪽 화살표 컴포넌트(Arrow Component) 방향을 향하게 됩니다.

    스켈레탈 메시 방향

  6. 컴포넌트(Components) 탭 으로 이동하여 메시(Mesh) 컴포넌트를 선택한 후 컴포넌트 추가(Add Component) 를 클릭하고 드롭다운 메뉴에서 SpringArm을 찾아 선택한 다음, 스프링 암 컴포넌트(Spring Arm Component) 의 이름을 'SpringArmComp '로 지정합니다.

    스프링 암 컴포넌트 추가

  7. 디테일 패널 로 이동하여 카메라 세팅(Camera Settings) 카테고리에 있는 폰 제어 회전 사용(Use Pawn Control Rotation) 을 활성화합니다.

    카메라 세팅

    폰 제어 회전 사용을 활성화하면 카메라가 스프링 암을 기준으로 회전합니다.

  8. 카메라(Camera) 카테고리 에서 소켓 오프셋(Socket Offset) 을 (0, 0, 30 )으로 설정한 다음, 트랜스폼(Transform) 카테고리 로 이동하여 SpringArmComp의 위치 를 (0, 0, 50 )으로 설정합니다.

    스프링 암 컴포넌트 세팅

  9. SpringArmComp를 선택한 상태에서 컴포넌트 추가(Add Component) 버튼을 클릭한 다음, 드롭다운 메뉴에서 카메라를 찾아 선택하여 CameraComp 라는 카메라 컴포넌트(Camera Component) 를 추가합니다.

    카메라 컴포넌트 추가

  10. 컴포넌트(Components) 탭에서 캐릭터 무브먼트 컴포넌트(Character Movement Component) 를 선택한 다음, 디테일 패널 로 이동하여 캐릭터 무브먼트(회전 세팅)(Character Movement (Rotation Settings)) 카테고리에 있는 컨트롤러 선호 회전 사용(Use Controller Desired Rotation)무브먼트 방향으로 회전 조정(Orient Rotation to Movement) 을 활성화합니다.

    캐릭터 무브먼트 회전 세팅

  11. 캐릭터 무브먼트: 걷기(Character Movement: Walking) 카테고리에 있는 베이스 회전 무시(Ignore Base Rotation) 변수를 활성화합니다.

    베이스 회전 무시 활성화

    베이스 회전 무시를 활성화하면 캐릭터가 현재 월드 회전을 유지하고 캐릭터가 서 있는 베이스의 회전에 발생한 모든 변화를 무시합니다.

  12. 캐릭터 무브먼트 내비 무브먼트(Character Movement Nav Movement) 카테고리 에서 무브먼트 기능(Movement Capabilities) 으로 이동한 후 추가 변수 세팅이 나타나도록 드롭다운 화살표를 선택한 다음, 크라우치 가능(Can Crouch) 부울 을 클릭하여 활성화합니다.

    크라우치 가능 부울 활성화

  13. 컴파일(Compile) 하고 저장(Save) 합니다.

    컴파일 및 저장 버튼

플레이어가 캐릭터를 제어하려면 캐릭터(Character) 클래스를 생성해야 합니다. 캐릭터는 캐릭터 무브먼트 컴포넌트(Character Movement Component)와 연동되는 폰(Pawn)으로서 인간형 캐릭터가 월드를 활보할 수 있는 로코모션 시스템을 지원합니다. 캐릭터를 단계적으로 설정하는 방법은 다음과 같습니다.

  1. C++ 클래스 마법사(C++ Class Wizard) 에서 PlayerCharacter 라는 새로운 캐릭터(Character) 클래스를 생성한 다음, PlayerCharacter.h 파일로 이동하여 아래의 클래스 정의를 선언합니다.

    protected:
    
    //스프링 암 컴포넌트가 플레이어 뒤에 있는 카메라를 따라갑니다.
    UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
    class USpringArmComponent* SpringArmComp;
    
    //플레이어가 카메라를 따라갑니다.
    UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
    class UCameraComponent* CameraComp; 
  2. PlayerCharactor.cpp 파일로 이동하여 아래의 클래스 라이브러리를 추가합니다.

    #include "Camera/CameraComponent.h"
    #include "GameFramework/SpringArmComponent.h"
    #include "GameFramework/CharacterMovementComponent.h"
  3. APlayerCharactor::APlayerCharacter 생성자 메서드에서 아래와 같이 선언합니다.

    // 클래스 컴포넌트 인스턴스화
    
    SpringArmComp = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArmComp"));
    
    CameraComp = CreateDefaultSubobject<UCameraComponent>(TEXT("CameraComp"));
    
    //캐릭터 메시 트랜스폼의 위치와 회전을 설정합니다.
    
    GetMesh()->SetRelativeLocationAndRotation(FVector(0.0f, 0.0f, -90.0f), FQuat(FRotator(0.0f, -90.0f, 0.0f)));
    
    // 클래스 컴포넌트를 디폴트 캐릭터의 스켈레탈 메시 컴포넌트에 어태치합니다.
    
    SpringArmComp->SetupAttachment(GetMesh());
    
    CameraComp->SetupAttachment(SpringArmComp,USpringArmComponent::SocketName);
    
    //스프링 암의 클래스 변수를 설정합니다.
    
    SpringArmComp->bUsePawnControlRotation = true;
    
    //캐릭터 무브먼트 컴포넌트의 클래스 변수를 설정합니다.
    
    GetCharacterMovement()->bOrientRotationToMovement = true;
    
    GetCharacterMovement()->bUseControllerDesiredRotation = true;
    
    GetCharacterMovement()->bIgnoreBaseRotation = true;
  4. 코드를 컴파일(Compile) 합니다.

  5. 에디터 에서 C++ 클래스(C++ Classes) 폴더 로 이동한 다음, PlayerCharacter 클래스를 우클릭하고 C++ 클래스 액션(C++ Class Actions) 드롭다운 메뉴에서 PlayerCharacter 기반 블루프린트 클래스 생성(Create Blueprint class based on PlayerCharacter) 을 선택합니다. 블루프린트의 이름을 Bp_PlayerCharacter 로 지정합니다.

    이미지를 클릭하면 확대됩니다.

  6. BP_PlayerCharacter 를 더블클릭하여 클래스 디폴트(Class Defaults) 를 연 다음, 컴포넌트(Components) 탭 에서 메시 (CharacterMesh0) 스켈레탈 메시 컴포넌트(Skeletal Mesh Component) 를 선택하고 디테일 패널 로 이동합니다.

    이미지를 클릭하면 확대됩니다.

  7. 메시(Mesh) 카테고리 에서 스켈레탈 메시(Skeletal Mesh) 변수 옆에 있는 드롭다운 화살표를 선택하고 드롭다운 메뉴에서 SK_Mannequin 을 선택합니다.

    스켈레탈 메시 선택

  8. 캐릭터의 스켈레탈 메시 가 아래 이미지에 보이는 것처럼 앞쪽 화살표 컴포넌트(Arrow Component) 방향을 향하게 됩니다.

    스켈레탈 메시 방향

  9. 컴파일(Compile) 하고 저장(Save) 합니다.

    컴파일 및 저장 버튼

입력 키 매핑 및 입력 무브먼트 이벤트 생성하기

W, A, S, D 같은 입력 키를 누르면 캐릭터가 움직이는 몇 가지 커스텀 로직을 설정해야 합니다.

  1. 편집(Edit) > 프로젝트 세팅(Project Settings) > 입력(Input) 으로 이동한 다음, 바인딩(Bindings) 카테고리 에서 액션 매핑(Action Mappings) 옆의 + 부호를 클릭하여 아래의 액션 매핑을 추가합니다.

    액션 매핑

    키 값

    점프

    스페이스 바

    앉기

    왼쪽 Ctrl

    스프린트

    왼쪽 Shift

    무브먼트 액션 매핑

  2. 바인딩(Bindings) 카테고리 에서 축 매핑(Axis Mappings) 옆에 있는 + 부호를 클릭하여 아래의 축 매핑 을 추가합니다.

    축 매핑

    키 값

    스케일

    MoveForward

    W

    1.0

    S

    -1.0

    오른쪽으로 이동

    D

    1.0

    A

    -1.0

    Turn

    마우스 X

    1.0

    LookUp

    마우스 Y

    -1.0

    입력 액션 매핑

  3. 콘텐츠 브라우저(Content Browser) 에서 BP_PlayerCharacter 를 더블클릭하여 클래스 디폴트(Class Defaults) 를 연 다음, 이벤트 그래프(Event Graph) 를 우클릭하고 드롭다운 메뉴에서 MoveForward 를 찾아 선택합니다.

    이미지를 클릭하면 확대됩니다.

  4. InputAxis MoveForward 노드의 실행 핀 을 밖으로 드래그한 후 드롭다운 메뉴에서 Add Movement Input 노드를 찾아 선택한 다음, InputAxis MoveForward 노드의 Axis Value 핀을 Add Movement Input 노드의 Scale Value 핀에 연결합니다.

    이미지를 클릭하면 확대됩니다.

  5. 이벤트 그래프(Event Graph) 를 우클릭하고 컨텍스트 메뉴에서 Get Control Rotation 을 찾아 선택한 후 Return Value 핀을 밖으로 드래그한 다음, 드롭다운 메뉴에서 Break Rotator 를 찾아 선택합니다.

    이미지를 클릭하면 확대됩니다.

  1. Break Rotator 노드의 Z(Yaw) 핀을 밖으로 드래그한 후 드롭다운 메뉴에서 Make Rotator 를 찾아 선택한 다음, Make Rotator 노드의 Return Value 핀을 밖으로 드래그한 후 드롭다운 메뉴에서 Get Forward Vector 를 찾아 선택합니다.

    이미지를 클릭하면 확대됩니다.

  2. Get Forward Vector 노드의 Return Value 핀을 밖으로 드래그하여 Add Movement Input 노드의 World Direction 핀에 연결합니다.

    이미지를 클릭하면 확대됩니다.

  3. 그래프를 다시 우클릭하고 입력 축 이벤트(Input Axis Event) 를 위해 오른쪽으로 이동(Move Right) 을 찾아 선택합니다.

    이미지를 클릭하면 확대됩니다.

  4. InputAxis MoveRight 노드의 실행 핀 을 밖으로 드래그한 후 드롭다운 메뉴에서 Add Movement Input 노드를 찾아 선택한 다음, InputAxis MoveRight 노드의 Axis Value 핀을 Add Movement Input 노드스케일 값(Scale Value) 핀에 연결합니다.

    이미지를 클릭하면 확대됩니다.

  5. Make Rotator 노드의 Return Value 핀을 밖으로 드래그한 후 드롭다운 메뉴에서 Get Right Vector 노드를 찾아 선택한 다음, Return Value 핀을 밖으로 드래그하여 Add Movement Input 노드의 World Direction 핀에 연결합니다.

    이미지를 클릭하면 확대됩니다.

  6. 완성된 무브먼트 입력 이벤트 블루프린트 그래프는 아래와 같습니다.

    이미지를 클릭하면 확대됩니다.

  7. 이벤트 그래프(Event Graph)우클릭 하고 InputAxis LookUp 이벤트 노드를 찾아 선택한 다음, 우클릭하고 Add Controller Pitch Input 노드를 찾아 선택합니다.

    이미지를 클릭하면 확대됩니다.

  8. InputAxis LookUp 노드의 Axis Value 핀을 밖으로 드래그하여 Add Controller Pitch Input 노드의 Val 핀에 연결합니다. InputAxis LookUp 노드의 실행 출력 핀 을 밖으로 드래그하여 Add Controller Pitch Input 노드의 실행 입력 핀 에 연결합니다.

    이미지를 클릭하면 확대됩니다.

  9. 이벤트 그래프(Event Graph) 를 우클릭한 후 InputAxis Turn 이벤트 노드를 찾아 선택한 다음, 우클릭하고 Add Controller Yaw Input 노드를 찾아 선택합니다.

    이미지를 클릭하면 확대됩니다.

  10. Turn 입력 축 노드의 Axis Value 핀에서 드래그하여 Add Controller Yaw Input 노드의 Val 핀에 연결합니다. InputAxis Turn 노드의 실행 출력 핀 을 밖으로 드래그하여 Add Controller Yaw Input 노드의 실행 입력 핀 에 연결합니다.

    이미지를 클릭하면 확대됩니다.

  11. 컴파일(Compile)저장(Save) 을 클릭합니다.

    컴파일 및 저장 버튼

미완성된 블루프린트

현재 프로세스 시점에서 블루프린트 그래프는 아래의 이미지와 유사합니다.

이미지를 클릭하면 확대됩니다.

W, A, S, D 같은 입력 키를 누르면 캐릭터가 움직이는 몇 가지 커스텀 로직을 설정해야 합니다.

  1. 편집(Edit) > 프로젝트 세팅(Project Settings) > 입력(Input) 으로 이동한 다음, 바인딩(Bindings) 카테고리 에서 액션 매핑(Action Mappings) 옆의 + 부호를 클릭하여 아래의 액션 매핑 을 추가합니다.

    액션 매핑

    키 값

    점프

    스페이스 바

    앉기

    왼쪽 Ctrl

    스프린트

    왼쪽 Shift

    무브먼트 액션 매핑

  2. 바인딩(Bindings) 카테고리 에서 축 매핑(Axis Mappings) 옆에 있는 + 부호를 클릭하여 아래의 축 매핑 을 추가합니다.

    축 매핑

    키 값

    스케일

    MoveForward

    W

    1.0

    S

    -1.0

    오른쪽으로 이동

    D

    1.0

    A

    -1.0

    Turn

    마우스 X

    1.0

    LookUp

    마우스 Y

    -1.0

    입력 액션 매핑

  3. PlayerCharacter.h에 아래의 클래스 메서드를 선언합니다.

    protected:
    
    //앞쪽/뒤쪽 입력을 위해 호출합니다.
    
    void MoveForward(float InputAxis);
    
    //왼쪽/오른쪽 입력을 위해 호출합니다.
    
    void MoveRight(float InputAxis);
  4. PlayerCharacter.Cpp에서 APlayerCharacter::MoveForwardAPlayerCharacter::MoveRight 클래스 메서드에 적용될 아래의 로직을 구현합니다.

    void APlayerCharacter::MoveForward(float AxisValue)
    {
        if ((Controller != nullptr) && (AxisValue != 0.0f))
        {
            // 앞쪽 찾기
            const FRotator Rotation = Controller->GetControlRotation();
            const FRotator YawRotation(0, Rotation.Yaw, 0);
    
            // 앞쪽 벡터 구하기
            const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
            AddMovementInput(Direction, AxisValue);
        }
    }
    
    void APlayerCharacter::MoveRight(float AxisValue)
    {
        if ((Controller != nullptr) && (AxisValue != 0.0f))
        {
            // 오른쪽 찾기
            const FRotator Rotation = Controller->GetControlRotation();
            const FRotator YawRotation(0, Rotation.Yaw, 0);
    
            // 오른쪽 벡터 구하기 
            const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
    
            // 해당 방향으로 이동 추가
            AddMovementInput(Direction, AxisValue);
        }
    }
  5. 그런 다음, APlayerCharacter::SetupPlayerInputComponent 메서드로 이동하여 아래의 코드를 구현합니다.

    //함수 기능을 입력에 바인딩하기 위해 호출
    void APlayerCharacter::SetupPlayerInputComponent(UInputComponent*)
    {
        Super::SetupPlayerInputComponent(PlayerInputComponent);
    
        PlayerInputComponent->BindAxis("MoveForward", this, &APlayerCharacter::MoveForward);
        PlayerInputComponent->BindAxis("MoveRight", this, &APlayerCharacter::MoveRight);
        PlayerInputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
        PlayerInputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);
    
    }
  6. 코드를 컴파일(Compile) 합니다.

작업 중인 코드

PlayerCharacter.h

    #include "CoreMinimal.h"
    #include "GameFramework/Character.h"
    #include "PlayerCharacter.generated.h"

    UCLASS()
    class CHARACTERMOVEMENT_API APlayerCharacter : public ACharacter
    {
        GENERATED_BODY()

    public:
        //이 캐릭터의 프로퍼티에 적용되는 디폴트값 설정
        APlayerCharacter();

    protected:
        // 게임 시작 또는 스폰 시 호출
        virtual void BeginPlay() override;

        //스프링 암 컴포넌트가 플레이어 뒤에 있는 카메라를 따라갑니다.
        UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
        class USpringArmComponent* SpringArmComp;

        //플레이어가 카메라를 따라갑니다.
        UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
        class UCameraComponent* CameraComp; 

        //앞쪽/뒤쪽 입력을 위해 호출합니다.
        void MoveForward(float InputAxis);

        //왼쪽/오른쪽 입력을 위해 호출합니다.
        void MoveRight(float InputAxis);

    public: 
        // 프레임마다 호출
        virtual void Tick(float DeltaTime) override;

        //함수 기능을 입력에 바인딩하기 위해 호출
        virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
    };

PlayerCharacter.Cpp

    #include "PlayerCharacter.h"
    #include "Camera/CameraComponent.h"
    #include "GameFramework/SpringArmComponent.h"
    #include "GameFramework/CharacterMovementComponent.h"

    // 디폴트값 설정
    APlayerCharacter::APlayerCharacter()
    {
        // 이 캐릭터가 프레임마다 Tick()을 호출하도록 설정합니다.  이 설정이 필요 없는 경우 비활성화하면 퍼포먼스가 향상됩니다.
        PrimaryActorTick.bCanEverTick = true;

        // 클래스 컴포넌트 인스턴스화
        SpringArmComp = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArmComp"));
        CameraComp = CreateDefaultSubobject<UCameraComponent>(TEXT("CameraComp"));

        //캐릭터 메시 트랜스폼의 위치와 회전을 설정합니다.
        GetMesh()->SetRelativeLocationAndRotation(FVector(0.0f, 0.0f, -90.0f), FQuat(FRotator(0.0f, -90.0f, 0.0f)));

        // 클래스 컴포넌트를 디폴트 캐릭터의 스켈레탈 메시 컴포넌트에 어태치합니다.
        SpringArmComp->SetupAttachment(GetMesh());
        CameraComp->SetupAttachment(SpringArmComp,USpringArmComponent::SocketName);

        //스프링 암의 클래스 변수를 설정합니다.
        SpringArmComp->bUsePawnControlRotation = true;

        //캐릭터 무브먼트 컴포넌트의 클래스 변수를 설정합니다.
        GetCharacterMovement()->bOrientRotationToMovement = true;
        GetCharacterMovement()->bUseControllerDesiredRotation = true;
        GetCharacterMovement()->bIgnoreBaseRotation = true;

    }

    // 게임 시작 또는 스폰 시 호출
    void APlayerCharacter::BeginPlay()

    {
        Super::BeginPlay();

    }

    void APlayerCharacter::MoveForward(float AxisValue)

    {
        if ((Controller != nullptr) && (AxisValue != 0.0f))
        {
            // 앞쪽 찾기
            const FRotator Rotation = Controller->GetControlRotation();
            const FRotator YawRotation(0, Rotation.Yaw, 0);

            // 앞쪽 벡터 구하기
            const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
            AddMovementInput(Direction, AxisValue);
        }
    }

    void APlayerCharacter::MoveRight(float AxisValue)
    {
        if ((Controller != nullptr) && (AxisValue != 0.0f))
        {
            // 오른쪽 찾기
            const FRotator Rotation = Controller->GetControlRotation();
            const FRotator YawRotation(0, Rotation.Yaw, 0);

            // 오른쪽 벡터 구하기 
            const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);

            // 해당 방향으로 이동 추가
            AddMovementInput(Direction, AxisValue);
        }
    }

    // 프레임마다 호출
    void APlayerCharacter::Tick(float DeltaTime)
    {
        Super::Tick(DeltaTime);

    }

    //함수 기능을 입력에 바인딩하기 위해 호출
    void APlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
    {
        Super::SetupPlayerInputComponent(PlayerInputComponent);
        PlayerInputComponent->BindAxis("MoveForward",this, &APlayerCharacter::MoveForward);
        PlayerInputComponent->BindAxis("MoveRight", this, &APlayerCharacter::MoveRight);
        PlayerInputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
        PlayerInputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);
    }

입력 키 매핑 및 입력 액션 이벤트 생성하기

이렇게 해서 전방 이동(Move Forward), 오른쪽으로 이동(Move Right), 올려 보기(LookUp), 회전(Turn) 입력 이벤트에 적용될 블루프린트 스크립팅 로직이 완성되면 점프(Jump), 앉기(Crouch), 스프린트(Sprint) 입력 이벤트에 적용될 액션 매핑(Action Mappings)을 구현해야 합니다.

  1. 이벤트 그래프(Event Graph) 를 우클릭한 다음, 이 블루프린트에 대한 모든 액션(All Actions for this Blueprint) 드롭다운 메뉴에서 Jump 액션 이벤트(Action Event) 를 찾아 선택합니다.

    이미지를 클릭하면 확대됩니다.

  2. Jump 입력 액션(InputAction Jump) 노드의 Pressed 실행 핀을 밖으로 드래그한 다음, 드롭다운 메뉴에서 캐릭터 함수 Jump 를 찾아 선택합니다.

    Jump 캐릭터 함수 추가

  3. Jump 입력 액션(InputAction Jump) 노드의 실행 핀Jump 노드의 실행 핀 에 연결합니다.

    이미지를 클릭하면 확대됩니다.

  4. Jump 입력 액션(InputAction Jump) 노드의 Released 실행 핀을 밖으로 드래그한 다음, 드롭다운 메뉴에서 캐릭터(Character) 함수 Stop Jumping 을 찾아 선택합니다.

    이미지를 클릭하면 확대됩니다.

  5. 이벤트 그래프(Event Graph) 를 우클릭하고 드롭다운 메뉴에서 Sprint 입력 액션(InputAction Sprint) 을 찾아 선택합니다.

    Sprint 입력 액션 추가

  6. 컴포넌트(Components) 탭 으로 이동한 다음, 캐릭터 무브먼트 컴포넌트(Character Movement Component) 를 클릭하여 이벤트 그래프(Event Graph) 로 드래그합니다.

    이미지를 클릭하면 확대됩니다.

  7. Character Movement 핀 을 밖으로 드래그한 다음, 드롭다운 메뉴에서 Set Max Walk Speed 노드를 찾아 선택합니다. Max Walk Speed 플로트 값을 1000 으로 설정한 다음, Sprint 입력 액션(InputAction Sprint) 노드의 눌림(Pressed) 실행 핀Set Max Walk Speed 노드의 입력 실행 핀에 연결합니다.

    이미지를 클릭하면 확대됩니다.

  8. Character Movement 핀 을 밖으로 드래그한 다음, 또 다른 Set Max Walk Speed 노드를 찾아 선택합니다. Max Walk Speed 플로트 값을 600 으로 설정한 다음, Sprint 입력 액션(InputAction Sprint) 노드의 Released 실행 핀을 Set Max Walk Speed 노드의 실행 입력 핀에 연결합니다.

    이미지를 클릭하면 확대됩니다.

  9. 이벤트 그래프(Event Graph) 를 우클릭하고 드롭다운 메뉴에서 Crouch 입력 액션 을 찾아 선택합니다.

    Crouch 입력 액션 추가

  10. Crouch 입력 액션(InputAction Crouch) 노드의 Pressed 실행 핀을 밖으로 드래그한 다음, 드롭다운 메뉴에서 캐릭터 클래스 함수 Crouch 를 찾아 선택합니다.

    이미지를 클릭하면 확대됩니다.

  11. Crouch 입력 액션(InputAction Crouch) 노드의 Released 실행 핀을 밖으로 드래그한 다음, 드롭다운 액션 메뉴에서 캐릭터 클래스 함수 Un Crouch 를 찾아 선택합니다.

    이미지를 클릭하면 확대됩니다.

  12. 블루프린트를 컴파일(Compile) 하고 저장(Save) 합니다.

    컴파일 및 저장 버튼

완성된 블루프린트

완성된 블루프린트는 아래의 이미지와 유사합니다.

이미지를 클릭하면 확대됩니다.

이렇게 해서 전방 이동(Move Forward) , 오른쪽으로 이동(Move Right) , 올려 보기(LookUp) , 회전(Turn) 입력 이벤트 에 적용될 코드 스크립팅 로직이 완성되면 점프(Jump) , 앉기(Crouch) , 스프린트(Sprint) 입력 이벤트에 적용될 액션 매핑(Action Mappings) 을 구현해야 합니다.

  1. PlayerCharacter.h 파일로 이동하여 아래의 클래스 메서드를 선언합니다.

    protected:
    
        //캐릭터 무브먼트 속도를 스프린트 값으로 설정합니다.
        void BeginSprint();
    
        //캐릭터 무브먼트 속도를 디폴트 속도 값으로 다시 설정합니다.
        void EndSprint();
    
        //캐릭터에게 앉기를 요청합니다.
        void BeginCrouch();
    
        //캐릭터에게 앉기 종료를 요청합니다.
        void EndCrouch();
  2. PlayerCharacter.cpp 파일에서 APlayerCharacter::BeginSprintAPlayerCharacter::EndSprint 클래스 메서드에 적용될 아래의 로직을 구현합니다.

    void APlayerCharacter::BeginSprint()
    {
        GetCharacterMovement()->MaxWalkSpeed = 1000.0f; 
    }
    
    void APlayerCharacter::EndSprint()
    {
        GetCharacterMovement()->MaxWalkSpeed = 600.f;
    }
  3. APlayerCharacter::BeginCrouchAPlayerCharacter::EndCrouch 메서드에 적용될 아래의 로직을 구현합니다.

    void APlayerCharacter::BeginCrouch()
    {
        Crouch();
    }
    
    void APlayerCharacter::EndCrouch()
    {
        UnCrouch();
    }
  4. APlayerCharacter:: ::SetupPlayerInputComponent 메서드로 이동하여 다음 코드를 선언합니다.

    void APlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
    {
    
        PlayerInputComponent->BindAction("Jump",IE_Pressed,this,&ACharacter::Jump);
        PlayerInputComponent->BindAction("Jump",IE_Released,this,&ACharacter::StopJumping);
        PlayerInputComponent->BindAction("Crouch",IE_Pressed,this,&APlayerCharacter::BeginCrouch);
        PlayerInputComponent->BindAction("Crouch",IE_Released,this,&APlayerCharacter::EndCrouch);
        PlayerInputComponent->BindAction("Sprint",IE_Pressed,this,&APlayerCharacter::BeginSprint);
        PlayerInputComponent->BindAction("Sprint",IE_Released,this,&APlayerCharacter::EndSprint);
    
    }
  5. 코드를 컴파일(Compile) 합니다.

완성된 코드

PlayerCharacter.h

    #pragma once

    #include "CoreMinimal.h"
    #include "GameFramework/Character.h"
    #include "PlayerCharacter.generated.h"

    UCLASS()
    class CHARACTERMOVEMENT_API APlayerCharacter : public ACharacter
    {
        GENERATED_BODY()

    public:
        //이 캐릭터의 프로퍼티에 적용되는 디폴트값 설정
        APlayerCharacter();

    protected:
        // 게임 시작 또는 스폰 시 호출
        virtual void BeginPlay() override;

        //스프링 암 컴포넌트가 플레이어 뒤에 있는 카메라를 따라갑니다.
        UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
        class USpringArmComponent* SpringArmComp;

        //플레이어가 카메라를 따라갑니다.
        UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
        class UCameraComponent* CameraComp; 

        //앞쪽/뒤쪽 입력을 위해 호출합니다.
        void MoveForward(float InputAxis);

        //왼쪽/오른쪽 입력을 위해 호출합니다.
        void MoveRight(float InputAxis);

        //캐릭터 무브먼트 속도를 스프린트 값으로 설정합니다.
        void BeginSprint();

        //캐릭터 무브먼트 속도를 디폴트 속도 값으로 다시 설정합니다.
        void EndSprint();

        //캐릭터에게 앉기를 요청합니다.
        void BeginCrouch();

        //캐릭터에게 앉기 종료를 요청합니다.
        void EndCrouch();

    public: 

        // 프레임마다 호출
        virtual void Tick(float DeltaTime) override;

        //함수 기능을 입력에 바인딩하기 위해 호출
        virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

    };

PlayerCharacter.cpp

    #include "PlayerCharacter.h"
    #include "Camera/CameraComponent.h"
    #include "GameFramework/SpringArmComponent.h"
    #include "GameFramework/CharacterMovementComponent.h"

    // 디폴트값 설정
    APlayerCharacter::APlayerCharacter()
    {
        // 이 캐릭터가 프레임마다 Tick()을 호출하도록 설정합니다.  이 설정이 필요 없는 경우 비활성화하면 퍼포먼스가 향상됩니다.
        PrimaryActorTick.bCanEverTick = true;

        // 클래스 컴포넌트 인스턴스화
        SpringArmComp = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArmComp"));
        CameraComp = CreateDefaultSubobject<UCameraComponent>(TEXT("CameraComp"));

        //캐릭터 메시 트랜스폼의 위치와 회전을 설정합니다.
        GetMesh()->SetRelativeLocationAndRotation(FVector(0.0f, 0.0f, -90.0f), FQuat(FRotator(0.0f, -90.0f, 0.0f)));

        // 클래스 컴포넌트를 디폴트 캐릭터의 스켈레탈 메시 컴포넌트에 어태치합니다.
        SpringArmComp->SetupAttachment(GetMesh());
        CameraComp->SetupAttachment(SpringArmComp,USpringArmComponent::SocketName);

        //스프링 암의 클래스 변수를 설정합니다.
        SpringArmComp->bUsePawnControlRotation = true;

        //캐릭터 무브먼트 컴포넌트의 클래스 변수를 설정합니다.
        GetCharacterMovement()->bOrientRotationToMovement = true;
        GetCharacterMovement()->bUseControllerDesiredRotation = true;
        GetCharacterMovement()->bIgnoreBaseRotation = true;
    }

    // 게임 시작 또는 스폰 시 호출
    void APlayerCharacter::BeginPlay()
    {
        Super::BeginPlay();

    }

    void APlayerCharacter::MoveForward(float AxisValue)
    {
        if ((Controller != nullptr) && (AxisValue != 0.0f))
        {
            // 앞쪽 찾기
            const FRotator Rotation = Controller->GetControlRotation();
            const FRotator YawRotation(0, Rotation.Yaw, 0);

            // 앞쪽 벡터 구하기
            const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
            AddMovementInput(Direction, AxisValue);
        }
    }

    void APlayerCharacter::MoveRight(float AxisValue)
    {
        if ((Controller != nullptr) && (AxisValue != 0.0f))
        {
            // 오른쪽 찾기
            const FRotator Rotation = Controller->GetControlRotation();
            const FRotator YawRotation(0, Rotation.Yaw, 0);

            // 오른쪽 벡터 구하기 
            const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);

            // 해당 방향으로 이동 추가
            AddMovementInput(Direction, AxisValue);
        }
    }

    void APlayerCharacter::BeginSprint()
    {
    GetCharacterMovement()->MaxWalkSpeed = 1000.0f;
    }

    void APlayerCharacter::EndSprint()
    {
        GetCharacterMovement()->MaxWalkSpeed = 600.f;
    }

    void APlayerCharacter::BeginCrouch()
    {
        Crouch();
    }

    void APlayerCharacter::EndCrouch()
    {
        UnCrouch();
    }

    // 프레임마다 호출
    void APlayerCharacter::Tick(float DeltaTime)
    {
        Super::Tick(DeltaTime);
    }

    //함수 기능을 입력에 바인딩하기 위해 호출
    void APlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
    {
        Super::SetupPlayerInputComponent(PlayerInputComponent);
        PlayerInputComponent->BindAxis("MoveForward",this, &APlayerCharacter::MoveForward);
        PlayerInputComponent->BindAxis("MoveRight", this, &APlayerCharacter::MoveRight);
        PlayerInputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
        PlayerInputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);
        PlayerInputComponent->BindAction("Jump",IE_Pressed,this, &ACharacter::Jump);
        PlayerInputComponent->BindAction("Jump",IE_Released,this, &ACharacter::StopJumping);
        PlayerInputComponent->BindAction("Crouch",IE_Pressed,this,&APlayerCharacter::BeginCrouch);
        PlayerInputComponent->BindAction("Crouch",IE_Released,this,&APlayerCharacter::EndCrouch);
        PlayerInputComponent->BindAction("Sprint",IE_Pressed,this, &APlayerCharacter::BeginSprint);
        PlayerInputComponent->BindAction("Sprint",IE_Released,this, &APlayerCharacter::EndSprint);
    }

게임 모드 설정하기

게임 모드는 게임의 여러 규칙을 정의합니다. 게임을 실행할 때 플레이어가 스폰되는 디폴트 폰(Pawn)도 이러한 규칙에 포함됩니다. 생성한 플레이어 캐릭터를 스폰하려면 규칙을 설정해야 합니다.

  1. 콘텐츠 브라우저(Content Browser) 에서 추가/임포트(Add/Import) 버튼을 클릭하고 새로운 블루프린트(Blueprint) 클래스를 생성합니다. 이때 부모 클래스 선택(Pick a Parent Class) 메뉴가 나타나면 게임 모드 베이스(Game Mode Base) 를 선택하고, 새로운 게임 모드 클래스의 이름을 Bp_GameMode 로 지정합니다.

    이미지를 클릭하면 확대됩니다.

  2. Bp_GameMode 를 더블클릭하여 클래스 디폴트를 연 다음, 디테일 패널의 클래스(Classes) 카테고리 로 이동하여 디폴트 폰 클래스(Default Pawn Class)로 Bp_PlayerCharacter 를 선택합니다.

    디폴트 폰 클래스 선택

  3. 블루프린트를 컴파일(Compile) 하고 저장(Save) 합니다.

    컴파일 및 저장 버튼

  4. 편집(Edit) > 프로젝트 세팅(Project Settings) > 맵 & 모드(Maps & Modes) 로 이동하여 디폴트 모드(Default Modes) 카테고리 에서 Bp_GameMode 를 선택합니다.

    이미지를 클릭하면 확대됩니다.

게임 모드는 게임의 여러 규칙을 정의합니다. 게임을 실행할 때 플레이어가 스폰되는 디폴트 폰(Pawn)도 이러한 규칙에 포함됩니다. 생성한 플레이어 캐릭터를 스폰하려면 규칙을 설정해야 합니다.

  1. 에디터(Editor)에서 C++ 클래스 폴더로 이동합니다. CharacterMovementGameModeBase를 우클릭하고 C++ 클래스 액션(C++ Class Actions) 메뉴 에서 CharacterMovementGameModeBase 기반 블루프린트 클래스 생성(Create Blueprint class based on your CharacterMovementGameModeBase) 을 선택하여 새로운 게임 모드 클래스의 이름을 Bp_GameMode** 로 지정합니다.

    이미지를 클릭하면 확대됩니다.

  2. Bp_GameMode 를 더블클릭하여 클래스 디폴트 를 연 다음, 디테일 패널의 클래스(Classes) 카테고리 로 이동하여 디폴트 폰 클래스(Default Pawn Class)로 Bp_PlayerCharacter를 선택합니다.

    디폴트 폰 클래스 선택

  3. 블루프린트를 컴파일(Compile) 하고 저장(Save) 합니다.

    컴파일 및 저장 버튼

  4. 편집(Edit) > 프로젝트 세팅(Project Settings) > 맵 & 모드(Maps & Modes) 로 이동하여 디폴트 모드(Default Modes) 카테고리 에서 Bp_GameMode 를 선택합니다.

    이미지를 클릭하면 확대됩니다.

로코모션 블렌드 스페이스 생성하기

이제 입력 함수 기능이 있으며 레벨에서 이동할 수 있는 캐릭터가 생겼으니 무브먼트 스테이트(걷기, 전력 질주, 달리기, 앉기)를 위한 블렌드 스페이스(Blend Spaces) 를 생성해야 합니다.

블렌드 스페이스는 두 입력값에 따라 애니메이션을 블렌딩하는 특수한 에셋입니다. 캐릭터의 이동 속도나 방향에 따라 앞뒤로, 좌우로 이동하는 자신만의 블렌드 스페이스를 만들 수 있습니다.

  1. 콘텐츠 브라우저(Content Browser) 에서 추가/임포트(Add/Import) > 애니메이션(Animation) > 블렌드 스페이스(BlendSpace) 를 클릭하고, 스켈레톤을 선택하라는 메시지가 나오면 UE4_Mannequin_Skeleton 을 선택한 후 블렌드 스페이스의 이름을 Locomotion_BS 로 지정합니다.

    블렌드 스페이스 생성

  2. Locomotion_BS 블렌드 스페이스(Blend Space)를 더블클릭하여 엽니다. 에셋 디테일(Asset Details) 탭에서 Axis Settings 카테고리로 이동한 후 가로축(Horizontal Axis)세로축(Vertical Axis) 옆에 있는 화살표를 선택하여 변수의 세부 사항을 확인합니다.

    에셋 디테일 Axis Settings

  3. 가로축(Horizontal Axis) 세팅에서 Name 변수를 Direction 으로 변경하고, Minimum Axis Value-180 , Maximum Axis Value180 으로 설정합니다.

    가로축 세팅

  4. 세로축(Vertical Axis) 세팅에서 Name 변수를 Speed 로 변경하고 Maximum Axis Value1000 으로 설정합니다.

    세로축 세팅

  5. 컴파일(Compile) 하고 저장(Save) 합니다.

    컴파일 및 저장 버튼

  6. 에셋 브라우저(Asset Browser) 로 이동하여 필터(Filters) 검색창에 Idle_Rifle_Hip 을 입력한 후 Idle_Rifle_Hip 에셋을 Direction 0.0 , Speed 0.0 으로 블렌드 스페이스(Blend Space) 에 드래그 앤 드롭합니다.

    이미지를 클릭하면 확대됩니다.

  7. 이전 단계를 반복하되, Idle_Rifle_Hip 에셋의 변수를 다음과 같이 설정합니다.

    • Direction 180 , Speed 0 .

    • Direction 90 , Speed 0 .

    • Direction -90 , Speed 0 .

    • Direction -180 , Speed 0 .

    이미지를 클릭하면 확대됩니다.

  8. 에셋 브라우저(Asset Browser) 탭의 필터(Filters) 검색창에 Walk_Fwd_Rifle_Ironsights 를 입력한 후 Walk_Fwd_Rifle_Ironsights 에셋을 Direction 0.0 , Speed 250 으로 블렌드 스페이스(Blend Space) 에 드래그 앤 드롭합니다.

    이미지를 클릭하면 확대됩니다.

  9. 다음으로 에셋 브라우저(Asset Browser) 탭의 필터(Filters) 검색창에 Walk_Lt_Rifle_Ironsights 를 입력한 후 Walk_Lt_Rifle_Ironsights 에셋을 Direction -90 , Speed 250 으로 블렌드 스페이스(Blend Space) 에 드래그 앤 드롭합니다.

    이미지를 클릭하면 확대됩니다.

  10. 에셋 브라우저(Asset Browser) 탭의 필터(Filters) 검색창에 Walk_Rt_Rifle_Ironsights 를 입력한 후 Walk_Rt_Rifle_Ironsights 에셋을 Direction 90 , Speed 250 으로 블렌드 스페이스 에 드래그 앤 드롭합니다.

    이미지를 클릭하면 확대됩니다.

  11. 에셋 브라우저(Asset Browser) 탭의 필터(Filters) 검색창에 Walk_Bwd_Rifle_Ironsights 를 입력한 후 Walk_Bwd_Rifle_Ironsights 에셋을 Direction 180 , Speed 250 으로 블렌드 스페이스(Blend Space) 에 드래그 앤 드롭한 다음, Direction -180 , Speed 250 으로 다시 드래그 앤 드롭합니다.

    이미지를 클릭하면 확대됩니다.

  12. 에셋 브라우저(Asset Browser) 탭의 필터(Filters) 검색창에 Jog_Fwd_Rifle 을 입력한 후 Jog_Fwd_Rifle 에셋을 Direction 0.0 , Speed 500 으로 블렌드 스페이스(Blend Space) 에 드래그 앤 드롭합니다.

    이미지를 클릭하면 확대됩니다.

  13. 에셋 브라우저(Asset Browser) 로 이동하여 필터(Filters) 검색창에 Jog_Lt_Rifle 을 입력한 후 Jog_Lt_Rifle 에셋을 Direction -90 , Speed 500 으로 블렌드 스페이스(Blend Space) 에 드래그 앤 드롭합니다.

    이미지를 클릭하면 확대됩니다.

  14. 에셋 브라우저(Asset Browser) 로 이동하여 필터(Filters) 검색창에 Jog_Rt_Rifle 을 입력한 후 Jog_Rt_Rifle 에셋을 Direction 90 , Speed 500 으로 블렌드 스페이스(Blend Space) 에 드래그 앤 드롭합니다.

    이미지를 클릭하면 확대됩니다.

  15. 에셋 브라우저(Asset Browser)필터(Filters) 검색창에 Jog_Bwd_Rifle_Ironsights 를 입력한 후 Jog_Bwd_Rifle_Ironsights 에셋을 Direction 180 , Speed 500 으로 블렌드 스페이스(Blend Space) 에 드래그 앤 드롭한 다음, Direction -180 , Speed 500 으로 하나 더 드래그 앤 드롭합니다.

    이미지를 클릭하면 확대됩니다.

  16. 에셋 브라우저(Asset Browser) 로 이동해서 Sprint_Fwd_Rifle_Ironsights 를 검색하고 선택한 후 Sprint_Fwd_Rifle_Ironsights 에셋을 Direction 0 , Speed 1000 으로 블렌드 스페이스(Blend Space) 에 드래그 앤 드롭하여 블렌드 스페이스를 완성합니다.

    이미지를 클릭하면 확대됩니다.

  17. 컴파일(Compile) 하고 저장(Save) 합니다.

    컴파일 및 저장 버튼

완성된 Locomotion_BS 는 아래 이미지와 같습니다.

완성된 로코모션 블렌드 스페이스

앉기 로코모션 블렌드 스페이스 생성하기

로코모션 블렌드 스페이스(Locomotion Blend Space)가 완성되었으니 이제 앉기 로코모션 블렌드 스페이스를 생성해야 합니다.

  1. 콘텐츠 브라우저(Content Browser) 에서 추가/임포트(Add/Import) > 애니메이션(Animation) > 블렌드 스페이스(BlendSpace) 를 클릭하고 스켈레톤을 선택하라는 메시지가 나오면 UE4_Mannequin_Skeleton 을 선택한 후 블렌드 스페이스의 이름을 LocomotionCrouch_BS 로 지정합니다.

  2. Locomotion_BS 블렌드 스페이스(Blend Space)를 더블클릭하여 엽니다. 에셋 디테일(Asset Details) 탭에서 Axis Settings 카테고리로 이동한 후 가로축(Horizontal Axis)세로축(Vertical Axis) 옆에 있는 화살표를 선택하여 변수의 세부 사항을 확인합니다.

    에셋 디테일 Axis Settings

  3. 가로축(Horizontal Axis) 세팅에서 Name 변수를 Direction 으로 변경하고, Minimum Axis Value-180 , Maximum Axis Value180 으로 설정합니다.

    앉기 가로축 세팅

  4. 세로축 세팅(Vertical Axis Settings) 에서 Name 변수를 Speed 로 변경하고 Maximum Axis Value300 으로 설정합니다.

    앉기 세로축 세팅

  5. 로코모션 블렌드 스페이스 생성하기 섹션에 나오는 이전 단계를 반복하되, 블렌드 스페이스에 넣는 에셋의 변수를 다음과 같이 설정합니다.

    애니메이션 에셋 이름

    Speed

    Direction

    Crouch_Idle_Rifle_Hip

    0

    0, 90, -90, 180, -180

    Crouch_Walk_Fwd_Rifle_Hip

    300

    0

    Crouch_Walk_Lt_Rifle_Hip

    300

    -90

    Crouch_Walk_Rt_Rifle_Hip

    300

    90

    Crouch_Walk_Bwd_Rifle_Hip

    300

    180, -180

  6. LocomotionCrouch_BS를 저장하고 컴파일합니다.

    컴파일 및 저장 버튼

완성된 LocomotionCrouch_BS 블렌드 스페이스(Blend Space)는 다음 그림과 같은 모습이 될 것입니다.

완성된 앉기 로코모션 블렌드 스페이스

애니메이션 블루프린트 생성하기

플레이어의 현재 액션에 따라 어떤 캐릭터 애니메이션을 재생할지 판별하는 애니메이션 블루프린트(Animation Blueprint) 가 필요합니다. 추가로 스테이트 머신(State Machine) 을 설정하여 걷기(Walk)앉기(Crouch) 스테이트를 생성하고 스테이트 간의 트랜지션을 설정해야 합니다.

  1. 콘텐츠 브라우저(Content Browser) 에서 추가/임포트(Add/Import) > 애니메이션(Animation) > 애니메이션 블루프린트(Animation Blueprint) 를 클릭하고 스켈레톤을 선택하라는 메시지가 나오면 UE4_Mannequin_Skeleton 을 선택한 후 애니메이션 블루프린트의 이름을 PlayerCharacter_AB 로 지정합니다.

    애니메이션 블루프린트 생성

  2. PlayerCharacter_AB 를 더블클릭하여 애니메이션 블루프린트를 엽니다. 내 블루프린트(My Blueprint) 탭에서 변수(Variables) 카테고리로 이동한 다음 인접한 + 기호를 선택하여 Is CrouchedIs Jumping 이라는 2개boolean 변수를 생성합니다.

    Is Crouched 및 Is Jumping 변수

  3. 이벤트 그래프(Event Graph) 탭을 클릭하고 Try Get Pawn Owner 노드의 Return Value 핀에서 드래그하여 드롭다운 메뉴에서 BP_PlayerCharacter 에 형변환(Cast to BP_PlayerCharacter) 을 검색하고 선택합니다.

    이미지를 클릭하면 확대됩니다.

  4. BP_PlayerCharacter 에 형변환(Cast to BP_PlayerCharacter) 노드의 As BP_PlayerCharacter 반환 핀에서 드래그하여 Get Is Crouched 를 검색하고 선택합니다.

    Get Is Crouched

  5. 내 블루프린트(My Blueprint) 탭으로 이동한 후, 변수(Variables) 카테고리의 Is Crouched 변수를 Get Is Crouched 노드의 반환 핀 에 드래그 앤 드롭합니다.

    이미지를 클릭하면 확대됩니다.

  6. BP_PlayerCharacter 에 형변환(Cast to BP_PlayerCharacter)출력 실행 핀 에서 드래그하여 Set Is Crouched 노드의 입력 실행 핀 에 연결합니다.

    이미지를 클릭하면 확대됩니다.

  7. BP_PlayerCharacter 에 형변환(Cast to BP_PlayerCharacter) 노드의 As BP_PlayerCharacter 반환 핀에서 드래그하여 모든 액션(All Actions) 드롭다운 메뉴에서 Get Pressed Jump 를 검색하고 선택합니다.

    Get Pressed Jump 액션 추가

  8. 내 블루프린트(My Blueprint) 탭에서 변수(Variables) 카테고리로 이동한 후 Is Jumping 변수를 Get Pressed Jump 노드의 반환 핀 에 드래그 앤 드롭합니다.

    이미지를 클릭하면 확대됩니다.

  9. Set Is Crouched 노드의 출력 실행 핀 에서 드래그하여 Set Is Jumping 노드의 입력 실행 핀 에 연결합니다.

    이미지를 클릭하면 확대됩니다.

  10. PlayerCharacter_AB 애니메이션 블루프린트를 컴파일(Compile) 하고 저장(Save) 합니다.

    컴파일 및 저장 버튼

  11. 변수(Variables) 카테고리에서 인접한 + 기호를 선택하여 SpeedDirection 이라는 float 변수 를 생성합니다.

    속도 및 방향 변수 생성

  12. BP_PlayerCharacter 에 형변환(Cast to BP_PlayerCharacter) 노드의 As BP_PlayerCharacter 반환 핀에서 드래그하고, 컨텍스트에 따라(Context Sensitive) 박스를 클릭하여 활성화 한 뒤 Get Velocity 를 검색하고 선택합니다.

    컨텍스트에 따라 검색한 Get Velocity 노드

  13. Get Velocity 노드의 Return Value 핀에서 드래그하여 액션(Actions) 드롭다운 메뉴에서 Vector Length 를 검색하고 선택합니다.

    Vector Length 노드 추가

  14. 내 블루프린트(My Blueprint) 탭의 Speed 변수를 Vector Length 노드의 vector Return Value 핀으로 드래그 앤 드롭합니다.

    이미지를 클릭하면 확대됩니다.

  15. 다음으로 Set Is Jumping 노드의 실행 출력 핀Set Speed 노드의 실행 입력 핀 에 연결합니다.

    이미지를 클릭하면 확대됩니다.

  16. BP_PlayerCharacter 에 형변환(Cast to BP_PlayerCharacter) 노드의 As BP_PlayerCharacter 반환 핀에서 드래그하여 Get Actor Rotation 을 검색하고 선택합니다.

    Get Actor Rotation 노드 추가

  17. GetActorRotation 노드의 rotator Return Value 핀에서 드래그하여 액션(Actions) 드롭다운 메뉴에서 Calculate Direction 을 검색하고 선택합니다.

    Calculate Direction 노드 추가

  18. 다음으로 Get Velocity 노드의 Vector Return Value 핀에서 드래그하여 Calculate Direction 노드의 Velocity 입력 핀 에 연결합니다.

    이미지를 클릭하면 확대됩니다.

  19. 내 블루프린트(My Blueprint) 탭에서 Direction 변수를 클릭하고 드래그하여 Calculate Direction 노드의 float Return Value 핀에 드롭합니다.

    이미지를 클릭하면 확대됩니다.

  20. 다음으로 Set Speed 노드의 실행 출력 핀Set Direction 노드의 실행 입력 핀 에 연결합니다.

    이미지를 클릭하면 확대됩니다.

  21. Blueprint Update Animation 이벤트(Event Blueprint Update Animation)실행 출력 핀 에서 드래그하여 BP_PlayerCharacter 에 형변환(Cast to BP_PlayerCharacter) 노드에 연결합니다.

    이미지를 클릭하면 확대됩니다.

  22. PlayerCharacter_AB 애니메이션 블루프린트컴파일(Compile) 하고 저장(Save) 합니다.

    컴파일 및 저장 버튼

완성된 애니메이션의 이벤트 그래프(Event Graph) 는 다음 그림과 같은 모습이 됩니다.

이미지를 클릭하면 확대됩니다.

애니메이션 스테이트 머신 생성하기

스테이트 머신(State Machine) 은 스켈레탈 메시(Skeletal Mesh) 애니메이션을 일련의 스테이트(States) 로 구성하는 모습에 대한 그래픽 시각화를 제공합니다. 이러한 스테이트에는 하나의 스테이트를 다른 스테이트와 블렌딩하는 방식을 제어하는 트랜지션 룰(Transition Rules) 이 적용됩니다. boolean 변수를 사용하여 이전 섹션에서 생성한 여러 로코모션 블렌드 스페이스(Blend Space) 사이를 트랜지션할 것입니다.

  1. PlayerCharacter_AB 애니메이션 블루프린트(Animation Blueprint) 내에서 애님 그래프(AnimGraph) 로 이동합니다.

    이미지를 클릭하면 확대됩니다.

    애님 그래프는 스켈레탈 메시의 최종 포즈를 평가하는 데 사용됩니다.

  2. AnimGraph 를 우클릭한 후 액션(Actions) 드롭다운 메뉴에서 스테이트 머신 새로 추가(Add New State Machine) 를 검색하고 선택합니다.

    Add New State Machine

  3. 스테이트 머신(State Machine) 노드의 이름을 Locomotion**으로 변경하고 노드를 더블클릭하여 그래프를 엽니다. Entry 핀에서 드래그하여 액션(Actions) 드롭다운 메뉴에서 스테이트 추가(Add State)** 를 선택합니다.

    이미지를 클릭하면 확대됩니다.

  4. 새로운 스테이트 이름을 Movement 로 지정하고 더블클릭하여 Movement 스테이트 노드를 엽니다. 에셋 브라우저(Asset Browser) 로 이동한 후 Locomotion_BS 를 검색하고 클릭하여 그래프로 드래그합니다.

    이미지를 클릭하면 확대됩니다.

  5. 내 블루프린트(My Blueprint) 탭에서 Speed float 변수를 클릭한 후 블렌드 스페이스(Blend Space)의 Speed 세로축으로 드래그합니다.

    이미지를 클릭하면 확대됩니다.

  6. 내 블루프린트(My Blueprint) 탭으로 돌아가서 Direction float 변수를 클릭한 다음 블렌드 스페이스(Blend Space)의 Direction 가로축으로 드래그합니다.

    이미지를 클릭하면 확대됩니다.

  7. Animation Pose 출력 핀을 출력 애니메이션 포즈(Output Animation Pose) 노드의 Result 핀에 연결합니다.

    이미지를 클릭하면 확대됩니다.

  8. 컴파일(Compile) 하고 저장(Save) 합니다.

    컴파일 및 저장 버튼

  9. Locomotion 스테이트 머신으로 돌아가서 Movement 스테이트 노드를 클릭하고 드래그하여 Crouch Movement 라는 새 애니메이션 스테이트를 생성합니다.

    이미지를 클릭하면 확대됩니다.

  10. 트랜지션 룰(Transition Rule) 노드를 더블클릭하여 애님 그래프(AnimGraph) 를 엽니다.

    이미지를 클릭하면 확대됩니다.

  11. 내 블루프린트(My Blueprint) 탭에서 변수(Variables) 카테고리로 이동한 후 Is Crouched boolean을 드래그하여 결과(Result) 노드의 Can Enter Transition 입력 핀에 연결합니다.

    이미지를 클릭하면 확대됩니다.

  12. Locomotion 스테이트 머신 그래프로 돌아가서 Crouch Movement 스테이트를 더블클릭하여 애님 그래프를 엽니다. 에셋 브라우저(Asset Browser) 에서 LocomotionCrouch_BS 를 검색하고 클릭하여 그래프로 드래그합니다.

    이미지를 클릭하면 확대됩니다.

  13. 내 블루프린트(My Blueprint) 탭에서 변수(Variables) 카테고리로 이동한 후 SpeedDirection float 변수를 각각 LocomotionCrouch_BS 의 해당 핀에 드래그하고, LocomotionCrouch_BSAnimation Pose출력 애니메이션 포즈(Output Animation Pose)Result 핀에 연결합니다.

    이미지를 클릭하면 확대됩니다.

  14. 애니메이션 블루프린트를 컴파일(Compile) 하고 저장(Save) 합니다.

    컴파일 및 저장 버튼

  15. Locomotion 애님 그래프로 돌아가서 CrouchMovement 애니메이션 스테이트를 클릭하고, 거기서 드래그하여 Movement 애니메이션 스테이트에 연결합니다.

    이미지를 클릭하면 확대됩니다.

  16. 트랜지션 룰(Transition Rule) 노드를 더블클릭하여 애님 그래프(AnimGraph) 를 엽니다.

    이미지를 클릭하면 확대됩니다.

  17. 내 블루프린트(My Blueprint) 탭 에서 *Is Crouched** 부울 변수를 클릭하여 애님 그래프(AnimGraph)로 드래그하고, **Get Is Crouched** 를 선택한 뒤 이 노드의 **출력 핀** 에서 드래그하여 드롭다운 액션 메뉴에서 **NOT Boolean** 을 검색하고 선택합니다.

    이미지를 클릭하면 확대됩니다.

  18. 그런 다음 NOT Boolean 의 반환 핀을 Can Enter Transition 의 입력 핀에 연결합니다.

    이미지를 클릭하면 확대됩니다.

  19. 컴파일(Compile) 하고 저장(Save) 합니다.

    컴파일 및 저장 버튼

  20. 애님 그래프(AnimGraph) 로 돌아와서 Movement 애니메이션 스테이트를 클릭하고 드래그하여 스테이트 추가(Add State) 를 선택합니다.

    이미지를 클릭하면 확대됩니다.

  21. 애니메이션 스테이트(Animation State) 의 이름을 Jump 로 변경하고 더블클릭하여 애님 그래프(AnimGraph)를 엽니다. 에셋 브라우저(Asset Browser) 로 이동하여 Jump_From_Jog 를 검색한 후 그래프로 드래그합니다.

    이미지를 클릭하면 확대됩니다.

  22. Play Jump_From_Jog 애니메이션 포즈를 출력 애니메이션 포즈 Result 핀에 연결하여 Jump 애니메이션 스테이트를 완성합니다.

    이미지를 클릭하면 확대됩니다.

  23. Locomotion 애님 그래프 로 돌아와서 Movement 에서 Jump 로 가는 트랜지션 룰(Transition Rule) 노드를 더블클릭하여 애님 그래프(AnimGraph) 를 엽니다.

    이미지를 클릭하면 확대됩니다.

  24. 트랜지션 룰(Transition Rule) 애님 그래프 내에서 내 블루프린트(My Blueprints) 탭으로 이동하여 Is Jumping boolean 변수를 결과(Result) 노드의 Can Enter Transition 입력 핀으로 드래그합니다.

    이미지를 클릭하면 확대됩니다.

  25. Locomotion 애님 그래프(AnimGraph)로 돌아간 다음, Jump 애님 노드를 클릭하고 노드에서 드래그하여 Movement 애님 그래프(AnimGraph) 노드로 가는 트랜지션을 생성 합니다.

    이미지를 클릭하면 확대됩니다.

  26. Jump 에서 Movement 로 가는 트랜지션 룰(Transition Rule) 노드를 더블클릭하여 애님 그래프(AnimGraph) 를 엽니다.

    이미지를 클릭하면 확대됩니다.

  27. 내 블루프린트(My Blueprint) 탭에서 *Is Crouched** 및 **Is Jumping** boolean 변수를 클릭하여 **애님 그래프(AnimGraph)** 로 드래그하고, 각 출력 핀에서 드래그하여 액션(Actions) 드롭다운 메뉴에서 **NOT Boolean** 을 검색하고 선택합니다.

    이미지를 클릭하면 확대됩니다.

  28. NOT Boolean 출력 핀에서 드래그하여 AND Boolean 을 검색하고 선택합니다.

    NOT Boolean을 AND Boolean에 연결

  29. Is CrouchedIs Jumping 과 연결된 NOT Boolean 노드의 출력 핀을 AND Boolean 노드의 입력 핀에 연결하고, AND Boolean 의 출력 핀을 결과(Result) 노드의 Can Enter Transition 입력 핀에 연결합니다.

    이미지를 클릭하면 확대됩니다.

  30. Locomotion 애님 그래프로 돌아와서 Crouch Movement 노드를 클릭하고 거기서 드래그하여 Jump 노드로 가는 트랜지션을 생성 합니다.

    이미지를 클릭하면 확대됩니다.

  31. Crouch Movement 에서 Jump 로 가는 트랜지션 룰(Transition Rule) 노드를 더블클릭하여 애님 그래프(AnimGraph) 를 엽니다.

    이미지를 클릭하면 확대됩니다.

  32. Crouch Movement 에서 Jump 로 가는 트랜지션 룰(Transition Rule) 애님 그래프(AnimGraph) 내에서 내 블루프린트(My Blueprints) 탭으로 이동하고 Is Jumping Boolean 변수를 클릭하여 결과(Result) 노드의 Can Enter Transition** 입력 핀으로 드래그합니다.

    이미지를 클릭하면 확대됩니다.

  33. Locomotion 애님 그래프로 돌아가서 Jump 노드에서 드래그하여 Crouch Movement 노드로 가는 트랜지션을 생성 합니다.

    이미지를 클릭하면 확대됩니다.

  34. Jump 에서 Crouch Movement 로 가는 트랜지션 룰(Transition Rule) 노드를 더블클릭하여 애님 그래프(AnimGraph) 를 엽니다.

    이미지를 클릭하면 확대됩니다.

  35. 내 블루프린트(My Blueprint) 탭에서 Is CrouchedIs Jumping boolean 변수를 클릭하여 애님 그래프(AnimGraph) 로 드래그합니다.

    이미지를 클릭하면 확대됩니다.

  36. Is Jumping boolean의 출력 핀에서 드래그하여 액션(Actions) 드롭다운 메뉴에서 NOT Boolean 을 검색하고 선택합니다. 그런 다음 Is Crouched boolean의 출력 핀에서 드래그하여 AND Boolean 을 검색하고 선택합니다. Is Jumping 에 연결된 NOT Boolean 출력 핀을 AND Boolean 입력 핀에 연결하고, AND Boolean 출력 핀을 Can Enter Transition 결과 핀에 연결하여 트랜지션 룰을 완성합니다.

    이미지를 클릭하면 확대됩니다.

  37. 완성된 Locomotion 애님 그래프(AnimGraph)는 아래 이미지와 같습니다.

    이미지를 클릭하면 확대됩니다.

  38. AnimGraph 로 이동하여 Locomotion 포즈 출력 핀을 최종 애니메이션 포즈(Output Pose)Result 핀에 연결합니다.

    이미지를 클릭하면 확대됩니다.

  39. 컴파일(Compile) 하고 저장(Save) 합니다.

    컴파일 및 저장 버튼

  40. 콘텐츠 브라우저(Content Browser) 에서 BP_PlayerCharacter 를 더블클릭하여 클래스 디폴트 를 연 후 컴포넌트 탭에서 Mesh 컴포넌트를 선택합니다. 그런 다음 디테일 패널 애니메이션(Animation) 카테고리 로 이동하여 Anim Class 변수의 드롭다운 메뉴에서 PlayerCharacter_AB 를 검색하고 선택합니다.

    이미지를 클릭하면 확대됩니다.

결과

이제 로직을 테스트할 차례입니다. 툴바에서 플레이(PIE) 를 선택하면 캐릭터 무브먼트를 W,A,S,D 키로 제어할 수 있습니다. 전력 질주하려면 왼쪽 shift를 누르고, 앉으려면 왼쪽 ctrl을 누르고, 점프하려면 스페이스 바를 누릅니다.

실행 중인 캐릭터 무브먼트

언리얼 엔진의 이전 버전을 위해 작성된 페이지입니다. 현재 언리얼 엔진 5 버전을 위해 업데이트되지 않았습니다.