Post List

2017/11/29

Unreal4__9_1_플레이어 공격 (Combo)

플레이어의 연속공격(Combo) 대해서 소개하겠습니다.  지금 플레이어는 마우스 좌클릭시 한가지 공격모션밖에 나오지 않는데연속 클릭시 4가지 공격모션이 이어져 나오도록 만들어보았습니다.

우선 콤보의 조건은
첫번째 플레이어가 공격상태일때 입니다 공격시 1콤보로 올려줍니다.
여기서 중요한 부분은 현재콤보에서 다음 콤보로 넘어가는 부분인데 공격모션인 부분과 처음 모션으로 돌아가는 모션 사이에 기준점을 두고기준점 이전에 공격 시도시 콤보로 이어지고 이전에 공격 시도없이 이후 프레임으로 넘어간다면 콤보에 대한 정보는 초기화가 이루어집니다 부분에 대해서는 밑에서 사진과 함께 다시 설명하겠습니다.


마우스   입력에 대한 처리는 C++에서 이루어지기 때문에, C++에서 먼저 작업을 진행하였습니다. Jplayer클래스에서 키입력에 따른 액션이 적용되기 때문에 Jplayer 클래스를 열어줍니다.

1
2
3
4
5
6
7
// Called to bind functionality to input
void AJPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
    Super::SetupPlayerInputComponent(PlayerInputComponent);
    
    PlayerInputComponent->BindAction("Attack", IE_Pressed, this, &AJPlayer::Attack);
cs
 마우스 좌클릭시 Attack()함수가 호출이 되도록 바인딩이 되어있습니다.
Attack함수를 보면
1
2
3
4
5
6
7
8
9
10
11
12
13
void AJPlayer::Attack()
{
    if(m_isAttack == false)
    {
        m_isAttack    = true;
        m_combo        = 1;
    }
    else
    {
        m_chainCombo = true;
    }
}
cs
m_isAttack 변수와 m_combo, m_chainCombo 새로운 변수들이 보입니다.
변수에 대해 설명드리자면 m_isAttack 플레이어가 공격중인지에 대한 boolean값이며,
m_combo 현재  콤보인지, m_chainCombo 콤보를 진행할지에대한 변수입니다.

여기서 콤보 진행이 되지 않을 경우 정보를 초기화해주는 함수도 추가하겠습니다.
1
2
3
4
5
6
7
void AJPlayer::UnAttack()
{
    AJCharacter::UnAttack();
    m_chainCombo = false;
    m_combo = 0;
}
cs

UnAttack()함수는 블루프린트에서 호출되는 함수입니다.

이제 어느정도 C++에서 마우스 입력에 따른 공격상태 설정이 되었으니 에디터로 돌아와서 블루프린트와 애니메이션 몽타주를 통해 콤보를 만들어보겠습니다.

먼저 공격 애니메이션을 몽타주로 만들어주었습니다이번에는 하나의 몽타주안에 여러 개의 애니메이션이 연결되어 들어가있는게 아니라 공격모션 1개가 몽타주인샘입니다.

1. 콤보에 대한 조건 처리 다음 동작에 대한 연결
플레이어의 블루프린트를 열어줍니다이벤트그래프로 이동한 다음 사진과 같이 콤보에 대한 노드들을 연결해주었습니다.  우선 노드를 보면 Mcombo C++에서 보았던 m_combo변수로 콤보 카운트가 저장되는 변수입니다.
Mcombo == 1 이라는건 처음 공격을 시도했다는 의미입니다이때는 콤보 아닌 일반 공격에 해당됩니다


2. 공격 상태 및 콤보가 True일 때 M Combo에 따른 애니메이션 몽타주 설정과 카운트 증가


조건이 충족되었으니, Branch Condition true 되므로 switch문에서 1 해당하는 실행핀이 활성화됩니다. Combo 1 해당하는 애니메이션 몽타주가 플레이 되고동시에 combo 2 올려줍니다.

combo2부터는 마우스의 입력에 따라 콤보가 될지 말지에가 결정이 됩니다.
특정 프레임까지 마우스 입력이 없다면 현재 공격 모션에서 끝나게 되고특정 프레임전에 마우스 입력이 발생할 경우 C++ 코드에서 구현했던것처럼 m_chaincombo 값은 true 되고 콤보 공격을 진행하게 되지요.

위 1번 블루프린트 사진을 다시 보면 m_chaincombo true 되면서 branch 실행흐름은 switch 노드로 흐르게됩니다. 그 전에 m_chaincombo는 다시 false로 변경이 되지요. 다음 콤보 조건을 체크하기 위함이랍니다. 그리고 m combo 값을 selection으로 전달되기 때문에 combo2 해당하는 애니메이션 몽타주가 플레이가 됩니다

3. 선택된 애니메이션 몽타주 플레이
현재 콤보 카운트에 맞는 애니메이션 몽타주가 선택되고 플레이 시켜줍니다.
애니메이션은 한번만 플레이되어야 하기 때문에 DoOnce노드를 추가해주었습니다.
애니메이션에서 특정 프레임을 기준으로 마우스의 추가 입력에 따라 콤보의 진행여부를 판단한다고 하였습니다.

기준을 저는 공격모션에서 다시 돌아오는 모션으로 바뀌는 중으로 지정했습니다.
 부분은 만드는사람 마음이지만다음 모션으로 넘어가기에 최대한 자연스러운 프레임까지를 마지노선으로 정하였기때문에 'Reset' 이라는 노티파이를 추가해주었습니다.


애니메이션 프레임이 Reset에 도달했을 때는 더 이상의 추가 공격이 없다는 의미로 해석이 되겠지요.



Reset Notify 활성화 되면공격  콤보에 대한 정보를 초기화 해줍니다 상태에 이르게 되면 공격을 해도 다시 처음 공격모션(combo 1)으로 돌아가게 된답니다.

  


마지막 콤보 모션을 보면 회전을 하면서 공격하는 모션입니다회전하면서 앞으로 이동값을 주어 좀더 생동적인 효과를 줘보겠습니다.

우선 애니메이션 특정 프레임구간동안 이벤트를 발생시키기 위해서 저는 AnimNotifyState 기능을 사용하였습니다.
커스텀 애님노티파이스테이트를 사용하려면 AnimNotifyState 상속받는 블루프린트를 하나 생성하셔야 합니다.




마우스 우클릭  블루프린트 클래스 생성을 누른후 AnimNotifyState 찾아 클릭  생성해줍니다그럼 위와같이 생성이 되면 이름을 'MoveAnimNotifyState' 변경해 줍니다.
  
이벤트를  애니메이션을 열고 스크롤을 내리면 노티파이라는 부분이 있습니다여기에 이벤트를 주고싶은 구간을 지정해주는 부분인데요 노티파이에 좌클릭후 노티파이스 스테이트 추가를 가면 방금 추가한 MoveAnimNotifyState 있습니다클릭을 해줍니다.
  
그럼 위와같이 구간을 나타내는 노티파이 애니 스테이트가 추가가 됩니다그럼 이동값을 넣어줄 구간을 지정해   저장을 해주고 아까 생성한 MoveNotifyAnimState 블루프린트를 열어줍니다.
   



AnimNotifyState 함수오버로딩을 통해 기존에 있던 함수를 재구현할  있는데 저는 매프레임에 이동값을 주어야 하기때문에 Received Notify Tick 함수만을 오버로딩  플레이어의 포워드 벡터를 얻어와 이동값으로 넣어주었습니다.

여기서 Scale Value 이동 비율을 지정해줄수도 있답니다.


그리고 저장을   게임을 플레이해보면 아까 지정한 프레임구간에서 앞으로 이동하는 효과가 보여지게 됩니다.

https://docs.unrealengine.com/latest/KOR/Engine/Animation/Sequences/Notifies/index.html