오늘 할 것
- 플레이어
- 애니메이션 붙이기
- 걷기/달리기/전력질주
- 상태간 트랜지션 애니메이션 연결
- 애니메이션 붙이기
트레일러 제작 시 참고 영상
엘든링 블러드본 모드 트레일러, 모드 따리인데도 트레일러가 사고싶게 만드는 매력을 가졌음 ㄷㄷ
스테미너 회복 계산식
// 초당 회복률을 실제 초당 회복량으로 바꾼 뒤, 이번 프레임 시간만큼만 회복 const float RecoveryAmountPerSecond = MaxStamina * StaminaRecoveryPerSecond / 100.f; const float RecoveryAmountThisFrame = RecoveryAmountPerSecond * DeltaTime; SetCurrentStamina(CurrentStamina + RecoveryAmountThisFrame);- DeltaTime은 30프레임 약 0.0333초, 60프레임 약 0.0167초, 120프레임 약 0.0083초로, RecoveryAmountPerSecond * 프레임시간은 프레임 당 스테미너 회복량이 됨
- RecoveryAmountPerSecond의 핵심은 초당 회복률을 최대 스테미너 숫자에 곱한 뒤 100으로 나눠 백분율화하는 것. 스테미너 회복은 최대 스테미너 관계없이 항상 같은 비율로 회복되어야 함
1. 로코모션 애니메이션
애니메이션 전체 분류
| 분류 | 에셋 수 | 내용 |
|---|---|---|
| Locomotion | 262 | Idle, Walk, Run, Sprint, Turn, Dodge, Roll |
| Attack | 55 | 콤보 공격, 공중 공격, 버프, 실행, 런 어택 |
| Hit | 49 | 피격, 넉다운, 블록, 사망, 일어나기 |
| 합계 | 366 | 캐릭터 애니메이션 전체 |
Locomotion 구조
| 폴더 | 에셋 수 | 구조 | 설계 용도 |
|---|---|---|---|
| Idle | 4 | 기본/전투 Idle, 전환 애니메이션 | Idle 상태 |
| WalkRunSprint/Walk/01_Walk | 30 | 10방향 × Start/Loop/Stop | 일반 걷기 |
| WalkRunSprint/Walk/02_Walk_Combat | 30 | 10방향 × Start/Loop/Stop | 전투 걷기 |
| WalkRunSprint/Walk/03_Walk_Block | 약 32 | 10방향 × Start/Loop/Stop, 일부 중복 | 방어 걷기 |
| WalkRunSprint/Run/01_Run | 30 | 10방향 × Start/Loop/Stop | 일반 달리기 |
| WalkRunSprint/Run/02_Run_Combat | 30 | 10방향 × Start/Loop/Stop | 전투 달리기 |
| WalkRunSprint/Sprint/01_Sprint | 11 | Loop, Lean L/R, Start, Stop, Turn L/R | 일반 전력질주 |
| WalkRunSprint/Sprint/02_Sprint_Combat | 11 | Combat Loop, Lean, Start, Stop, Turn | 전투 전력질주 |
| Turn | 12 | 90/180 좌우, 일반/전투/방어 | 제자리 회전/피벗 |
| Dodge | 34 | 8방향 Dodge, Dodge to Run | 회피 |
| Roll | 34 | 8방향 Roll, Roll to Run | 구르기 |
Walk/Run 방향
| 방향명 | 의미 |
|---|---|
| F_0 | 전방 |
| F_L_45 | 전방 좌 45도 |
| F_R_45 | 전방 우 45도 |
| F_L_90 | 좌측 |
| F_R_90 | 우측 |
| B_180 또는 B_0 | 후방 |
| B_L_45 | 후방 좌 45도 |
| B_R_45 | 후방 우 45도 |
| B_L_90 | 후방 좌 90도 |
| B_R_90 | 후방 우 90도 |
- 특징: 10방향 Start / Loop / Stop 세트 기반 구조
설계 결론
| 영역 | 추천 방식 |
|---|---|
| Walk/Run Loop | Walk용 방향 BlendSpace, Run용 방향 BlendSpace 분리 |
| Walk/Run Start, Stop | 방향별 Start, Stop 상태로 별도 처리 |
| Sprint | 일반 방향 BlendSpace보다 Forward Loop + Lean L/R + Start/Stop/Turn 구조 |
| 180도 피벗 | Turn/01_Turn의 AS_Turn_180_L/R부터 사용 |
| Combat/Block | 나중에 CombatMode, BlockMode가 생기면 별도 세트로 확장 |
| Dodge/Roll | 로코모션 안정화 후 액션 상태나 몽타주로 연결 |
AnimBP 권장 상태 구조
| 상태 | 역할 |
|---|---|
| Idle | 입력 없음 |
| Start | 정지 상태에서 이동 시작 |
| WalkRunLocomotion | Walk/Run 방향성 Loop |
| Stop | 이동 중 입력 해제 |
| SprintStart | 전력질주 시작 |
| SprintLoop | 전력질주 유지, 좌우 Lean |
| SprintTurn | 전력질주 중 좌우 턴 |
| SprintStop | 전력질주 정지 |
| Pivot180 | 입력 방향 급반전 시 180도 회전 |
C++에서 AnimBP에 넘기면 좋은 값
| 값 | 용도 |
|---|---|
| MovementState | Walk/Run/Sprint 분기 |
| bHasMoveInput | Idle/Start/Stop 판단 |
| Speed | 이동 중 여부, 블렌딩 보조 |
| LastMoveInput2D | 입력 방향 판단 |
| MoveInputWorldDirection | 피벗/Start 방향 판단 |
| MoveInputLocalDirection | 방향 BlendSpace 입력 |
| DirectionAngle | -180 ~ 180 방향 선택 |
| bSprintLockedAfterExhausted | 전력질주 애니메이션 차단/상태 보조 |
2. 액션 구조
현재 문제점
'액션'에 대한 정의가 모호하다
- Player 엑셀의 ActionData 시트로 포함돼있음
- 여기에 전력질주, 구르기/회피, 공격, 가드를 한꺼번에 관리하려니 이상해짐
지금 단계에서 착용 아이템이란 개념이 없으므로 플레이어가 공격하는건 무조건 대검의 공격, 가드하면 대검의 가드가 됨
하지만 지금 구조로는 추후 아이템 시스템을 도입할 수 없음. 플레이어의 액션 데이터에서 아이템 데이터로 의존성이 생기고 테이블이 더러워질 가능성이 농후함
액션의 특징; 정확한 정의
'액션'이라는 단어는 정확히 무엇을 지칭하는가? 지금의 범위는 너무 넓다.
- 스테미너를 소모하는 행위
- 플레이어의 기본 이동과 구분되는 별개의 애니메이션이 출력되는 행위
이 게임에서 액션의 범위는 어디까지인가?
- 특수 이동
- 구르기
- 회피
- 대쉬(미정)
- 점프(구현x)
- 무기 공격
- 약공
- 강공
- 스킬
- 무기 가드
- 사용 가능한(액티브) 아이템/스킬
(이 때 걷기/달리기는 액션으로 간주하지 않는다)
구조
액션에 필요한 것:
- 비용, 조건, 제약 등의 수치
- 몽타주 관련 정보
핵심은 액션의 데이터와 몽타주를 따로 관리하는 것. 왜냐하면:
- 하나의 액션에 두 개 이상의 몽타주가 필요할 수 있음 - 비전투/전투 상태, 무기 상태에 따른 다른 몽타주 재생 등
- 액션 데이터는 대분류만 한다 - '약공'에 대검/창/직검 등이 조합될 수 있음
결론
- 따라서 지금의 Player_ActionData는 잘못됐고, 플레이어 도메인를 제거한 순수 Action 데이터테이블로 독립시켜야 함.
- 액션 별 무브셋은 Moveset 또는 ActionAnimationData로 분리
- 이후에 아이템, 무기 데이터를 도입하면 액션데이터 아이디와 무브셋 아이디만 넣어주면 쉽게 액티브로 확장됨
걷기 블렌딩
Walk BlendSpace 배치:
| 입력 방향 | Angle | 애니메이션 |
|---|---|---|
| W | 0 | F_0 |
| W + A | -45 | F_L_45 |
| A | -90 | F_L_90 |
| S + A | -135 | B_L_45 |
| S | -180 / 180 | B_0 또는 B_180 |
| S + D | 135 | B_R_45 |
| D | 90 | F_R_90 |
| W + D | 45 | F_R_45 |
| 키보드로 걸을 때 블렌딩이 안됐던 이유: |
- 이동방향각도를 C++ 클래스에서 넘겨주고 있었는데, 키보드는 입력이 디지털이므로 각도간 전환에 보간처리가 안되고 있었음
float ABAPlayerCharacter::GetMoveInputDirectionAngle() const { const FVector LocalDirection = GetMoveInputLocalDirection(); if (LocalDirection.IsNearlyZero()) { return 0.f; } return FMath::RadiansToDegrees(FMath::Atan2(LocalDirection.Y, LocalDirection.X)); }- 각도 보간처리를 ABP에서 노드로 진행.
bWasMoveLastFrame을 기준으로 0값과 방향각도 값을 보간해 블렌드스페이스에 적용
