오전 : 공격 애니메이션 구현
오후 :
용어 설명
1. 애니메이션 노티파이 :
애니메이션 구간마다 원하는 트리거를 기입하는 방법.
2. 노티파이 스테이트 :
사물이나 공격 뒤에 과녁 잡을 때 사용하는 방법
3. 뎁스 블렌드 :
블렌드 깊이값을 이용하여;. 얼마나 적용할지 정한다.
4. Additive :
다중치를 섞어준다 ? 히트 모션 ?
Tip
1. 언리얼에서 열겨형을 사용시. 설계를 다하고 사용하는걸 권장한다.
이유는 사용하다가 변경할 시. 적용되어있는 데이터를 자동변경을 해주지 않기 때문. 즉 다 수동으로 변경해야하니. 사용시 주의하자
2. 언리얼에서는 unsigned char 를 사용안하고 uint8을 사용한다.
3. ECC_GameTraceChannel 과 EnginChannel를 햇갈리는 경우가 많으니 주의할것.
따로 공부해서 정리해둘것
1.
앞서 각 연타에 맞는 애니메이션은 구현한걸 이용해서 구현한다.
노티파이 변수를 만들 때.
UFUNCION으로 진행한다.
애니메이션 노티파이 :
애니메이션 구간마다 원하는 트리거를 기입하는 방법.
노티파이 스테이트 :
사물이나 공격 뒤에 과녁 잡을 때 사용하는 방법
Attack1 파일 클릭
원하는 구간에 클릭 > 우클릭 > 새 노티파이 생성 > Attack 설정3
(노티파이 줄에 우클릭을 해야 새 노티파이 버튼이 보임)
동일하게 끝부분에 AttackEnd 노티파이 생성
중간에 재공격 허용할 부분인 AttackEnable 생성
앞서 설정한것을 Attack4 번까지 4개를 동일 작업을 진행.
AnimInstance 헤더파일에 선언
PlayerAnimInstance.h
public:
void Attack();
public:
//노티파이 함수는 void AnimNotify_노티파이이름() 의 형태로 만든다.
UFUNCTION()
void AnimNotify_Attack();
UFUNCTION()
void AnimNotify_AttackEnable();
UFUNCTION()
void AnimNotify_AttackEnd
PlayerAnimInstance.cpp
void UPlayerAnimInstance::AnimNotify_Attack()
{
PrintViewport(1.f, FColor::Red, TEXT("Attack"));
}
void UPlayerAnimInstance::AnimNotify_AttackEnable()
{
PrintViewport(1.f, FColor::Red, TEXT("AttackEnable"));
mAttackEnable = true;
}
void UPlayerAnimInstance::AnimNotify_AttackEnd()
{
PrintViewport(1.f, FColor::Red, TEXT("AttackEnd"));
mAttackIndex = 0;
mAttackEnable = true;
}
수업에서는 몬스터라도 있어야 공격 히트 모션이 있을테니. 추후 구현하고
이번시간에는 연공 기능만 구현한다.
애니메이션 그래프 화면에서
우클릭 > mSpeed Get > > 검색 > bool 포즈 블랜딩
포즈 블랜딩 디테일 란에 최하위의 "활성화 시 자손 리셋" 체크.
앞서 생성한 ANDRUN에서 CachePoss를 생성 후 IdleAndRun으로 이름변경
그 후 앞서 만든 캐시포즈를 생성 후 Attack에 연결 후 블렌딩에 연결
그 후 애니메이션은 재공격이 아닌 에니메이션 끝난걸 확인을 하기위해
변수 1개를 더 선언
PlayerAnimInstance.h
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = true))
bool mAttack;
PlayerAnimInstance.cpp
UPlayerAnimInstance::UPlayerAnimInstance()
{
mMoveDir = 0.f;
mAttack = false; <<< 추가!
mAttackEnable = true;
mAttackIndex = 0;
}
void UPlayerAnimInstance::Attack()
{
// 공격 불가능 상태일때는 공격키 무반응으로 설정
if (!mAttackEnable)
return;
//공격중에 다시 공격버튼을 클릭 못하도록 불가능상태로 변경
mAttackEnable = false;
// Montage_IsPlaying : 인자로 들어간 몽타주가 재생중인지 판단
if (!Montage_IsPlaying(mAttackMontageArray[mAttackIndex]))
{
Montage_SetPosition(mAttackMontageArray[mAttackIndex], 0.f);
Montage_Play(mAttackMontageArray[mAttackIndex]);
mAttackIndex = (mAttackIndex + 1) % mAttackMontageArray.Num();
mAttack = true; <<< 추가!
}
else
mAttackEnable = true; <<< 추가!
}
void UPlayerAnimInstance::AnimNotify_AttackEnd()
{
PrintViewport(1.f, FColor::Red, TEXT("AttackEnd"));
mAttackIndex = 0;
mAttackEnable = true;
mAttack = false; <<< 추가!
}
우클릭 > bone 검색 > 최상위 '본 별로 레이어드' 클릭
디테일란 > 레이어 설정 > 인덱스 클릭 > + 버튼 클릭
본 이름란에 기준으로 나눌 본 이름을 기입.
뎁스 블렌드 1로 설정
메시 스페이스 회전 블렌드 체크. (테스트 필수)
아래 사진처럼 복사해서 구축
프로젝트 세팅으로 키입력을 액션매핑으로 한다.이름은 Jump
PlayerCharacter.h
public:
void JumpKey();
PlayerCharacter.cpp
APlayerCharacter::APlayerCharacter()
{
GetCharacterMovement()->JumpZVelocity = 550.f;
}
void APlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
PlayerInputComponent->BindAction<APlayerCharacter>(TEXT("Jump"), EInputEvent::IE_Pressed, this, D&APlayerCharacter::JumpKey);
}
void APlayerCharacter::JumpKey()
{
Jump();
}
PlayerAnimInstance.h
UENUM(BlueprintType)
enum class EPlayerAnimType : uint8
{
Ground,
Jump,
Fall,
Death
};
protected:
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = true))
EPlayerAnimType mAnimType;
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = true))
bool mGround;
PlayerAnimInstance.cpp
UPlayerAnimInstance::UPlayerAnimInstance()
{
mMoveDir = 0.f;
mAttack = false;
mAttackEnable = true;
mAttackIndex = 0;
mAnimType = EPlayerAnimType::Ground; <<< 추가!
mGround = true; <<< 추가!
}
PlayerAnimInstance.cpp
void UPlayerAnimInstance::NativeUpdateAnimation(float DeletaSeconds)
{
Super::NativeUpdateAnimation(DeletaSeconds);
APlayerCharacter* PlayerCharacter = Cast<APlayerCharacter>(TryGetPawnOwner());
if (IsValid(PlayerCharacter))
{
UCharacterMovementComponent* Movement = PlayerCharacter->GetCharacterMovement();
mSpeedRatio = Movement->Velocity.Size() / Movement->MaxWalkSpeed;
mGround = Movement->IsMovingOnGround(); <<< 추가!
}
}
PlayerCharacter.h
bool mDeath;
PlayerChracter.cpp
mDeath = false;
PlayerCharacter.cpp
void APlayerCharacter::JumpKey()
{
if (mDeath)
return;
else if (mAnimInst->GetPlayerAnimType() != EPlayerAnimType::Ground)
return;
Jump();
mAnimInst->Jump();
}
PlayerAnimInstance.h
public:
void Jump();
PlayerAnimInstance.cpp
void UPlayerAnimInstance::Jump()
{
mAnimType = EPlayerAnimType::Jump;
}
주의할점 :
언리얼에서는 열거형을 쓸때는 가급적이면 전부 설계를 다하고 할것.
중간에 사용하다가 변경할 일이 있어 변경하면 변경작업을 안해줘서. 수동으로 직접 다해야하는 참사가 발생함.
우클릭 > Machine 검색 > 새 스테이트 머신 생성 클릭 >
Jump로 이름 변경 > 더블클릭 > 선 연결해서 새 스테이트 > JumpStart > e디테일에 진입시 리셋 체크 > JumpStart 더블클릭 > Jump Start 애니메이션 검색 후 연결
JumpStart - Jump 연결선 클릭 후
자동 규칙 체크
: 완료되면 자동으로 넘어가는 기능
프로젝트 세팅 > 콜리전
Object Channels : 물체 충돌
Trace Channels : 레이저를 쏴서 해당 좌표 충돌. ex.FPS 총 발사체,
무시 :
충돌할 경우 통과한다.
둘중 하나라도 무시가 체크 되어있다면 무시처리가 된다.
오버랩 :
무시처럼 통과는 하지만 충돌 이벤트 트리거가 작동된다.
블록 :
통과하지 못하고 부딪힌다.
기본 반응 :
언리얼에서 만든 기본체널에서 어떤 상호작용을 할것인지 선택.
콜리전 켜짐 :
Query Only : 물리 엔진이 필요없을 때 선택.
Physics Only : 물리 엔진이 필요하다면 선택.
Collision Enable : 둘다 상황에 맞게 할때 선택.
트레이스 타입 :
Visivlity : 벽뒤에 물체를 렌더링 안하도록 설정할때 관련된 옵션값.
설정한 값은 DefaultEngin.ini 에 저장된다
ECC_GameTraceChannel 과 EnginChannel를 햇갈리는 경우가 많으니 주의할것.