애니메이션 Montage 생성 및 Notify 추가
- 원하는 공격 모션이 나오는 시점에 Notify를 배치하여 공격 범위에 해당하는 AttackCollision을 활성화할 시점 명시
- Hitbox1: 공격 범위 활성화
- HitboxEnd1: 공격 범위 비활성화
Animation Notify Delegate 함수 바인딩
BaseCharacter.h
UFUNCTION()
void AttackNotify(FName NotifyName, const FBranchingPointNotifyPayload& Payload);
BaseCharacter.cpp
void ABaseCharacter::BeginPlay()
{
Super::BeginPlay();
//애니메이션 Notify 이벤트 연결
if (UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance())
{
AnimInstance->OnPlayMontageNotifyBegin.AddDynamic(this,&ABaseCharacter::AttackNotify);
}
PreLoadCharacterStats();
PreLoadAttackCollisions();
PreLoadCharacterAnim();
}
void ABaseCharacter::AttackNotify(const FName NotifyName, const FBranchingPointNotifyPayload& Payload)
{
if (!NotifyName.IsValid()||AttackCollisions.IsEmpty()) return;
// Determin the type of attack by name
FString NotifyNameString=NotifyName.ToString();
// Hitbox
if(NotifyNameString.Contains(TEXT("Hitbox")))
{
TCHAR LastChar = NotifyNameString[NotifyNameString.Len() - 1];
int32 AttackNumber = FCString::Atoi(&LastChar)-1;
//UE_LOG(LogTemp, Log, TEXT("Parsed Attack Number: %d"), AttackNumber);
// Activate Collision in proper location
if (AttackCollisions[AttackNumber])
{
// Deactivate Collision
if (NotifyNameString.Contains(TEXT("End")))
{
DeactivateAttackCollision(AttackNumber);
UE_LOG(LogTemp,Warning,TEXT("Deactivate Collision! (Index: %d)"),AttackNumber);
}
else // Activate Collision
{
AttackCollisions[AttackNumber]->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
UE_LOG(LogTemp,Warning,TEXT("Activate Collision! (Index: %d)"),AttackNumber);
}
}
else
{
UE_LOG(LogTemp,Warning,TEXT("Activate Failed!"));
}
return;
}
}
- 공격 모션에 따른 Notify 처리용 함수 AttackNotify 함수 생성
- Notify의 이름을 기준으로 어떤 동작을 할지 결정
- Hitbox 관련된 동작의 경우 이름의 숫자를 기준으로 배열의 몇번째 인덱스의 콜리전을 활성화해야 하는지 판별
AttackCollision Overlap Delegate 함수 바인딩
void ABaseCharacter::PreLoadAttackCollisions()
{
if (UGameInstance* GameInstance=GetGameInstance())
{
if (UDataLoaderSubSystem* Loader=GameInstance->GetSubsystem<UDataLoaderSubSystem>())
{
if (UEnum* Type=StaticEnum<EAttackType>())
{
const int32 n=Type->NumEnums();
AttackCollisions.SetNum(n-1);
for (int32 i=0;i<n-1;i++)
{
FString TypeName=Type->GetNameStringByIndex(i);
UE_LOG(LogTemp,Warning,TEXT("Current RowName: %s, Current Index: %d"),*TypeName,i);
const FName RowName=FName(CharacterType+"_"+TypeName);
FAttackCollisionData Data=Loader->InitializeAttackCollisionData(RowName);
if (Data.Scale!=FVector::ZeroVector)
{
//Create Collision and Attacth to Socket
UShapeComponent* AttackCollision = NewObject<UShapeComponent>(this,USphereComponent::StaticClass());
AttackCollision->SetupAttachment(GetMesh());
AttackCollision->SetRelativeLocation(Data.Location);
AttackCollision->SetRelativeScale3D(Data.Scale);
AttackCollision->SetCollisionEnabled(ECollisionEnabled::NoCollision);
//Bind Overlap Event
AttackCollision->OnComponentBeginOverlap.AddDynamic(this,&ABaseCharacter::OnAttackOverlap);
AttackCollisions[i]=AttackCollision;
}
}
}
}
}
}
- AttackCollision 관련 데이터를 로드하는 함수인 PreLoadAttackCollisions 함수 생성
- Enum으로 만들어진 EAttackType의 이름을 이용해 CharacterType과 조합하여 캐릭터에 알맞은 동작의 공격 범위 데이터 로드
- NewObject로 Collision 데이터에 맞게 생성 및 부착한 후 비활성화 상태로 변경
ㅡ> 공격 범위가 활성화되지 않는 에러 발생, 해결과정 아래 서술
NewObject로 만든 Component
- NewObject<T>()로 생성한 컴포넌트는 Unreal Engine의 Actor들의 Components 배열에 자동으로 추가되지 않음.
- RegisterComponent()는 엔진에 사용할 것이라 알려주는 역할을 하지만, Actor에 등록되지 않은 경우 호출할 수 없음.
- 그래서 먼저 AddInstanceComponent()를 호출한 후 RegisterComponent()를 호출
ㅡ> 공격 범위에 맞게 콜리전 활성화, 비활성화 성공
특정 캐릭터의 데미지 중복 적용 오류
- 특정 캐릭터만 공격 시 2번의 피격 판정을 받는 에러 발생
- 두 캐릭터의 블루프린트 옵션에서 차이점을 찾던 중 Generate Overlap Event 체크박스가 2개다 체크된 캐릭터에게 피격 판정이 중복 발생하는 것을 발견
- 결과적으로 비활성화할 쪽의 옵션을 비활성화하면서 에러 해결
참고자료
'프로젝트 > CCFF' 카테고리의 다른 글
미친 선인장과 분노의 버섯 - #10 동작에 알맞은 콜리전, Hit 관련 정보 매핑 구조 설계 (0) | 2025.04.08 |
---|---|
미친 선인장과 분노의 버섯 - #9 격투게임을 위한 사용자 정의 ApplyDamage(Helper class), TakeDamage(Interface) 구현 (0) | 2025.04.07 |
[Project] 미친 선인장과 분노의 버섯 - #7 공격시 콜리전 생성 방식 결정 + 캐릭터별 알맞은 데이터 로딩 로직 (0) | 2025.04.03 |
[Project] 미친 선인장과 분노의 버섯 - #6 구조체 추가 정의 + DataLoader Update (0) | 2025.04.02 |
[Project] 미친 선인장과 분노의 버섯 - #5 DataLoader SubSystem (0) | 2025.04.01 |