스테이트 에일리어스와 컨듀잇

DevBison·2025년 8월 27일

UE5 애님 블루프린트: 스테이트 에일리어스·컨듀잇·캐시드 포즈로 점프/로코모션 정리

목적: 선 엉킴 없이 점프(시작–체공–착지)와 기본 이동(Idle/Run)을 확장 가능한 구조로 만드는 방법을 정리


0) 미리보기: 최종 구조

  • 큰 흐름: Locomotion ↔ Jump(에일리어스) ↔ Land(에일리어스)
  • 점프 관련 라인은 에일리어스로 묶어서 선을 최소화

1) 코멘트 생성 (주석)

  • 복잡해지면 코멘트를 먼저 달아 구획을 나눠두는 게 유지보수에 유리

2) 스테이트 에일리어스란?

  • 스테이트가 많아질수록 선이 복잡해짐 → “에일리어스”로 묶으면 한 점으로 정리 가능

  • 연결선을 직접 늘리는 게 아니라 “들어올 수 있는 상태 집합”을 선언하는 개념


3) 스테이트·컨듀잇 개념 정리

  • 스테이트: 애니메이션 플레이 단위(Idle, Run, JumpStart, Fall, Land 등)

  • 컨듀잇: if/switch 같은 분기 허브(1↔N, N↔N 가능)

  • 들어오는 조건과 나가는 조건을 각각 정의해 흐름을 명확히


4) 점프 중 Run이 재생되는 문제 잡기 (지상 체크)

문제: 점프해도 이동속도 때문에 Run이 계속 실행됨 → 땅 위일 때만 Run 허용

1) AnimInstance 변수 추가

// PlayerDefaultAnimInstance.h
UPROPERTY(BlueprintReadOnly, Category="Movement")
bool mGround = false;
  1. NativeUpdateAnimation에서 갱신

  • 팁: CharacterMovement->IsMovingOnGround() 또는 IsFalling()를 사용하면 안정적
// PlayerDefaultAnimInstance.cpp (개념 예시)
void UPlayerDefaultAnimInstance::NativeUpdateAnimation(float DeltaSeconds)
{
    Super::NativeUpdateAnimation(DeltaSeconds);

    APawn* Pawn = TryGetPawnOwner();
    if (!Pawn) return;

    ACharacter* Char = Cast<ACharacter>(Pawn);
    if (!Char) return;

    const UCharacterMovementComponent* Move = Char->GetCharacterMovement();
    if (!Move) return;

    mGround = Move->IsMovingOnGround(); // 또는 !Move->IsFalling()
}
  1. 애님BP에서 And Boolean으로 속도>0 AND mGround 로 Run 허용


5) Jump 스테이트 구성(기본형)

  • JumpStart는 루프 X (한 번만 재생)

  • Idle/Run → Jump 전이는 “지상 아님(Not mGround)”로 시작 가능하지만, 아래 7)처럼 C++ 시그널을 쓰면 더 안정적

  • 전이를 매번 그리면 선이 복잡 → 에일리어스로 치환

6) 스테이트 에일리어스로 점프 라인 정리

  • JumpAlias에 Jump 관련 스테이트들을 모아두고, 외부에선 JumpStart 같은 핵심 스테이트 한 번만 연결

7) 캐시드 포즈로 Locomotion 재사용

  • Locomotion을 한 번 계산해 캐시에 저장 → Jump 스테이트머신 내부에서도 동일 포즈를 재사용

  • Jump 스테이트머신 안에서 “Use cached pose 'Locomotion'”로 간단히 참조

8) 디버깅 포인트

  • 프리뷰 인스턴스가 아닌 실제 스폰된 캐릭터 인스턴스로 디버깅해야 변수 값이 제대로 보임

  • 붕 떠있다면 전이 조건이나 에일리어스 체크 대상을 재확인

9) C++에서 점프 시그널 주입(mJump)

  1. AnimInstance 변수·함수 추가

// PlayerDefaultAnimInstance.h
UPROPERTY(BlueprintReadOnly, Category="Movement")
bool mJump = false;

UFUNCTION(BlueprintCallable)
void SetJump(bool bIn) { mJump = bIn; }
  1. 캐릭터에서 AnimInstance 참조 캐싱

// PlayerCharacter.h
UPROPERTY()
UPlayerDefaultAnimInstance* AnimInst = nullptr;

// PlayerCharacter.cpp
void APlayerCharacter::BeginPlay()
{
    Super::BeginPlay();
    AnimInst = Cast<UPlayerDefaultAnimInstance>(GetMesh()->GetAnimInstance());
}
  1. 점프 입력에서 시그널 On/Off

void APlayerCharacter::JumpKey()
{
    Jump(); // 실제 점프 실행
    if (AnimInst) AnimInst->SetJump(true);
}

void APlayerCharacter::Landed(const FHitResult& Hit)
{
    Super::Landed(Hit);
    if (AnimInst) AnimInst->SetJump(false);
}
  • 착지 시점에 mJump를 false로 돌려놓아야 다음 점프가 정상 동작
  • Landed 오버라이드를 쓰면 블루프린트 없이도 깔끔히 복귀
  1. 애님BP 전이 조건 교체

  • Jump → JumpStart: Not mGround 대신 mJump 사용(입력 신호 기반이라 반응성이 좋고 불필요한 공중 전이를 방지)

10) 점프 파이프라인 마무리 (Start → Fall → Land)

  • JumpStart → 자동 규칙 On(끝나면 Fall)

  • Fall: Jump_Apex 같은 체공 동작(루프는 어색하면 Off)

  • Jump → Fall: mGround가 false일 때 유지

  • Land 스테이트 추가(착지 모션)

  • Land → Locomotion: 자동 규칙 On, 그리고 Landed에서 mJump=false로 돌아오므로 자연스러운 복귀

11) 에일리어스 체크 범위 점검

  • Jump 에일리어스에는 Locomotion·Land를 체크(이동/착지에서 점프로 들어올 수 있음)
  • Land 에일리어스에는 Fall만 체크(체공에서 착지로만 들어오도록)
  • 체크 누락/과다 체크는 전이 혼선을 유발 → 붕 뜨는 문제의 흔한 원인

12) 자주 하는 실수와 보완 팁

  • mGround를 속도로 추정하지 말고 CharacterMovement의 IsMovingOnGround/IsFalling로 판단
  • JumpStart/Fall/Land는 루프를 신중히(대부분 비루프)
  • mJump 플래그는 입력 순간 On, 착지 시 Off가 가장 안전
  • Land 전이는 “mGround == true”로 명확히, Locomotion 복귀는 자동 규칙 On
  • 캐시드 포즈는 “계산 중복 방지 + 일관된 포즈 공유”가 목적(성능과 구조 모두 이점)
  • 전이 규칙 안에 “Blend Time”을 케이스별로 다르게 설정해 자연스러움 확보

13) 체크리스트

  • AnimInstance에 mGround, mJump를 UPROPERTY(BlueprintReadOnly)로 선언
  • NativeUpdateAnimation에서 mGround 갱신
  • 캐릭터 BeginPlay에서 AnimInstance 캐싱
  • Jump 입력 시 mJump=true, Landed 시 mJump=false
  • JumpStart → Fall 자동 규칙 On
  • Land → Locomotion 자동 규칙 On
  • 에일리어스 체크 대상 재확인(Jump: Locomotion/Land, Land: Fall)
  • Run 조건은 “속도>0 AND mGround”

14) 마무리

이 구성은 선이 적고, 전이 조건이 명확하며, 확장성(2단 점프, 점프 공격, 공중 대시 등)이 좋다. 이후 공중 공격을 추가해도 Jump 에일리어스 내부에서만 관리하면 외부 선은 깔끔하게 유지된다.

profile
응애 개발자

0개의 댓글