목차
- 서론
- 공격 상태 enum 만들기
- 블루프린트에서 비점거 상태로 돌아가기
- c++에서 비점거 상태로 돌아가기
- 무기가 없을 때 공격방지
- 공격 중 이동방지
1. 서론
현재 공격 애니메이션 작동 방식은 연속된 입력을 가하면 계속 애니메이션을 초기화해서 재생한다. 또한 애니메이션 재생 중 이동이 가능한데 이 부분을 막아보려고 한다.
2. 공격 상태 enum 만들기
전에 캐릭터의 무기 장착 상태에 따른 enum을 만들었던 것처럼 캐릭터의 액션 상태에 따른 enum을 만들 것이다.
캐릭터타입 헤더파일로 들어가보자
UENUM(BlueprintType)
enum class EActionState : uint8
{
EAS_Unoccupied UMETA(DisplayName = "Unoccoupied"),
EAS_Attacking UMETA(DisplayName = "Attacking")
};
다음과 같이 열거형 클래스를 만든다.
첫번째 EAS_Unoccupied 상태는 캐릭터를 조종하고 있지 않은 상태로 이 상태에서는 어떤 행동이든 할 수 있다.
두번째는 말 그대로 공격중일 때 적용할 상태이다.
이제 캐릭터 클래스로 돌아가 이 상태를 적용하자.
private:
EActionState ActionState = EActionState::EAS_Unoccupied;
프라이빗 영역에 다음과 같이 선언하자. 그리고 이제 공격 시 이 상태를 변경해 주면 된다.
void AKnight::Attack()
{
if (ActionState == EActionState::EAS_Unoccupied)
{
PlayAttackMontage();
ActionState = EActionState::EAS_Attacking;
}
}
PlayAttackMontage() 함수는 몽타주를 플레이하는 부분만 따로 빼내서 함수로 만든 것이고 그 외에 이제 if 문을 통해 캐릭터의 상태를 확인하고 비점거 상태일 때만 몽타주를 재생할 수 있게 한다.
이제 이렇게 하면 공격 중인 것을 알 수 있다. 하지만 이렇게만 하면 다시는 비점거 상태가 될 수 없다. 이것을 컴파일하고 비점거 상태로 돌아가보자
3. 비점거 상태로 돌아가기
비점거 상태로 돌아가는 것은 블루프린트에서 진행할 것이고 애님노티파이를 이용할 것이다.
다시 어택 몽타주로 들어가자
노티파이 섹션에서 새 노티파이를 생성한다.
노티파이를 공격이 끝나기 직전 부분에 놓는다. 애니메이션이 끝나는 정확한 지점에 노티파이를 설정할 경우 원하는 대로 작동을 하지 않을 수 있기 때문에 살짝 여유를 주는 것이 좋다.
이제 해당 몽타주를 쓰고 있는 애니메이션 블루프린트에서 이 노티파이를 쓸 수 있다.
캐릭터 애니메이션블루프린트로 들어가자
이벤트그래프에서 우클릭을 하고 노티파이의 이름을 검색하면 해당 노티파이를 불러올 수 있다.
해당 노티파이가 호출되면 작동할 동작을 만들면 되는데 우리가 할 일은 캐릭터의 열거형을 변경하는 것이다.
우클릭을 해서 캐릭터 인스턴스를 가져오자
c++에서 설정을 했었기 때문에 값을 가져올 수 있다.
이제 액션 스테이트를 가져오면 되는데 현재 블루프린트에 노출되도록 설정이 되어있지 않아 아무것도 나타나지 않는다.
캐릭터 헤더파일로 돌아가 액션스테이트 변수를 블루프린트리드라이트로 설정한다. 그리고 보호영역으로 옮기자. 프라이빗 영역에서는 메타데이터를 지정하지 않는 한 블루프린트에서 볼 수 없고 굳이 프라이빗 영역에 넣을 필요가 없기 때문이다.
이제 컴파일을 하자.
그 후 액션 스테이트를 바꾸면 된다.
4. c++에서 비점거 상태로 돌아가기
캐릭터 인스턴스를 불러오고 액션스테이트를 바꾸는 부분을 c++에서 함수로 만들 수도 있다. 블루프린트로 하나 C++에서 하나 성능차이는 없어서 편하거나 혹은 팀 규칙에 맞게 쓰면 된다고 한다.
// 캐릭터.h
protected:
UFUNCTION(BlueprintCallable)
void AttackEnd();
블루프린트에서 호출가능한 함수로 만들고 이를 정의하자.
void AKnight::AttackEnd()
{
ActionState = EActionState::EAS_Unoccupied;
}
위와 같이 정의하고 컴파일을 한다.
이제 노드들을 연결해 주자. 이렇게 해서 연속된 입력으로 애니메이션을 초기화하는 것을 방지하였다.
5. 무기가 없을 때 공격 방지
이번에는 무기가 없을 때 공격을 하지 못하게 방지하자. 다시 비주얼 스튜디오로 돌아간다.
void AKnight::Attack()
{
if (ActionState == EActionState::EAS_Unoccupied && CharacterState != ECharacterState::ECS_Unequipped)
{
PlayAttackMontage();
ActionState = EActionState::EAS_Attacking;
}
}
공격 부분 함수 if문에서 캐릭터 상태가 비무장 상태가 아니면 공격을 할 수 있게 바꾸면 된다.
해당 조건문이 너무 길어 이를 보기 쉽게 바꿀 수도 있다.
const bool bCanAttack =
ActionState == EActionState::EAS_Unoccupied &&
CharacterState != ECharacterState::ECS_Unequipped;
if (bCanAttack)
{
/// 이하생략
해당 조건식을 보면 딱 봐도 여러 곳에서 쓸 수 있을 것 같이 생겼다. 이를 함수로 바꾸자.
// 캐릭터 헤더파일
protected:
bool CanAttack();
// cpp
bool AKnight::CanAttack()
{
return ActionState == EActionState::EAS_Unoccupied &&
CharacterState != ECharacterState::ECS_Unequipped;
}
이제 무기가 없으면 공격하지 못하게 막았다.
6. 공격 중 이동방지
이번에는 공격하고 있을 때는 움직이지 못하게 하자.
void AKnight::Move(const FInputActionValue& Value)
{
if (ActionState == EActionState::EAS_Attacking) return;
// 이하 생략
간단하게 캐릭터를 이동하는 함수에 공격 중일때는 리턴을 시키면 된다.
이제 컴파일을 하고 확인하면 공격중 이동 및 재공격을 못하는 것을 알 수 있다.
'게임프로그래밍 > 실습1' 카테고리의 다른 글
[언리얼 실습] 19. 메타사운드를 활용하여 랜덤사운드 재생하기 (0) | 2024.10.26 |
---|---|
[언리얼 실습] 18. 메타사운드를 활용하여 효과음 추가 (0) | 2024.10.26 |
[언리얼 실습] 16. 애니메이션 몽타주로 공격 모션 만들기 (0) | 2024.10.25 |
[언리얼 실습] 15. 애니메이션 블루프린트 정리하기 (0) | 2024.10.13 |
[언리얼 실습] 14. Blend Poses 를 이용하여 상태에 따른 애니메이션 보여주기 (0) | 2024.10.13 |