12 - Animation, Attack,Jump... Etc

Overcle·2023년 2월 14일
0

학원

목록 보기
4/29

오전 : 공격 애니메이션 구현
오후 :

용어 설명
1. 애니메이션 노티파이 :
애니메이션 구간마다 원하는 트리거를 기입하는 방법.
2. 노티파이 스테이트 :
사물이나 공격 뒤에 과녁 잡을 때 사용하는 방법
3. 뎁스 블렌드 :
블렌드 깊이값을 이용하여;. 얼마나 적용할지 정한다.
4. Additive :
다중치를 섞어준다 ? 히트 모션 ?

Tip
1. 언리얼에서 열겨형을 사용시. 설계를 다하고 사용하는걸 권장한다.
이유는 사용하다가 변경할 시. 적용되어있는 데이터를 자동변경을 해주지 않기 때문. 즉 다 수동으로 변경해야하니. 사용시 주의하자
2. 언리얼에서는 unsigned char 를 사용안하고 uint8을 사용한다.
3. ECC_GameTraceChannel 과 EnginChannel를 햇갈리는 경우가 많으니 주의할것.

따로 공부해서 정리해둘것
1.

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;
}

수업에서는 몬스터라도 있어야 공격 히트 모션이 있을테니. 추후 구현하고
이번시간에는 연공 기능만 구현한다.

2. 달리기 애니메이션


애니메이션 그래프 화면에서

우클릭 > 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;  <<< 추가!
}

3. 본 레이어


우클릭 > bone 검색 > 최상위 '본 별로 레이어드' 클릭

디테일란 > 레이어 설정 > 인덱스 클릭 > + 버튼 클릭

본 이름란에 기준으로 나눌 본 이름을 기입.
뎁스 블렌드 1로 설정
메시 스페이스 회전 블렌드 체크. (테스트 필수)

아래 사진처럼 복사해서 구축

4. 점프


프로젝트 세팅으로 키입력을 액션매핑으로 한다.이름은 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 연결선 클릭 후

자동 규칙 체크
: 완료되면 자동으로 넘어가는 기능

5. 충돌처리


프로젝트 세팅 > 콜리전

Object Channels : 물체 충돌
Trace Channels : 레이저를 쏴서 해당 좌표 충돌. ex.FPS 총 발사체,

무시 :
충돌할 경우 통과한다.
둘중 하나라도 무시가 체크 되어있다면 무시처리가 된다.
오버랩 :
무시처럼 통과는 하지만 충돌 이벤트 트리거가 작동된다.
블록 :
통과하지 못하고 부딪힌다.


기본 반응 :
언리얼에서 만든 기본체널에서 어떤 상호작용을 할것인지 선택.


콜리전 켜짐 :
Query Only : 물리 엔진이 필요없을 때 선택.
Physics Only : 물리 엔진이 필요하다면 선택.
Collision Enable : 둘다 상황에 맞게 할때 선택.

트레이스 타입 :
Visivlity : 벽뒤에 물체를 렌더링 안하도록 설정할때 관련된 옵션값.

설정한 값은 DefaultEngin.ini 에 저장된다

ECC_GameTraceChannel 과 EnginChannel를 햇갈리는 경우가 많으니 주의할것.

profile
게임 프로그래머 지망생의 발자취

0개의 댓글