문제 상황
- 현재 같은 공격 동작을 움직이지 않고 연속해서 실행하면 OnComponentOverlapBegin에 바인딩한 함수가 처음에만 호출
- 같은 공격 동작에는 활성화하는 콜리전이 동일
- 현재 캐릭터 설계 구조상 동작마다 콜리전이 매핑된 형태
- 매핑된 콜리전을 애님 노티파이 시점에 따라 활성, 비활성하는 형태
- 방금 실행한 동작과 다른 동작을 실행하면 여전히 정상 동작
해결 과정
- 로그 확인결과 콜리전 활성화, 비활성화 로직은 문제 없이 애님 노티파이에 따라 실행 중
- OnComponentOverlapBegin 함수는 Overlap이 시작될 때 호출되는 함수
- Overlap이 어떤식으로 인지되는지에 대한 명확한 이해 필요
- 조사 결과 Overlap은 상태로 관리
- 이미 겹쳐있는 상태에서는 오버랩 상태가 변화하지 않았으니 OverlapBegin 호출 X
- 현재 SetCollisionEnabled()를 이용해 활성, 비활성 중
- 콜리전을 끄면 그냥 관련 연산만을 그만두는 것이지 Overlap 관련 상태를 활성, 비활성화하는 과정에서 Overlap 상태를 업데이트 하지는 않음
ㅡ> 결과적으로 현재 콜리전을 활성, 비활성하는 것은 불필요한 계산을 줄이는 취지 외에는 원하는 방향으로 작용하지 않음
ㅡ> 같은 공격이 여러번 실행되어도 OverlapBegin에 바인딩된 함수를 매번 호출하기 위해선 Overlap 상태를 변화시켜 주는 로직이 필요 - UpdateOverlap: 오버랩 관련 상태를 업데이트 해주는 함수
ㅡ> But, 말 그대로 현재 상태를 Update만 하므로 SetCollisionEnabled로 활성, 비활성하는 것과 마찬가지로 상태가 그대로라면 BeginOverlap은 호출되지 않음 - SetCollisionEnabled를 호출했을 때, 현재 register되는 Component가 아니라면 ClearSkipUpdateOverlaps+UpdateOverlaps 를 호출 X
void USceneComponent::ClearSkipUpdateOverlaps()
{
if (ShouldSkipUpdateOverlaps())
{
bSkipUpdateOverlaps = false;
if (GetAttachParent())
{
GetAttachParent()->ClearSkipUpdateOverlaps();
}
}
}
- 해당 함수는 오버랩 업데이트 스킵 플래그를끄는 함수
ㅡ> 결과적으로 계산해놨던 오버랩 관련 데이터를 쓸 수 없게 된다
ㅡ> 겹쳐있는 액터들에 대해서도 매번 업데이트가 필요한 현재 호출이 필요한 함수
void UPrimitiveComponent::SetGenerateOverlapEvents(bool bInGenerateOverlapEvents)
{
if (bGenerateOverlapEvents != bInGenerateOverlapEvents)
{
bGenerateOverlapEvents = bInGenerateOverlapEvents;
OnGenerateOverlapEventsChanged();
}
}
void UPrimitiveComponent::OnGenerateOverlapEventsChanged()
{
ClearSkipUpdateOverlaps();
}
- SetGenerateOverlapEvents(): 콜리전에서 오버랩 이벤트를 발생시킬 것인지 설정하는 함수
- 해당 함수에서 현재 필요한 ClearSkipUpdateOverlaps 호출
// Deactivate Collision
if (NotifyNameString.Contains(TEXT("End")))
{
CurrentActivatedCollision=-1;
DeactivateAttackCollision(AttackNumber);
AttackCollisions[AttackNumber]->SetGenerateOverlapEvents(false);
//UE_LOG(LogTemp,Warning,TEXT("Deactivate Collision! (Index: %d)"),AttackNumber);
}
else // Activate Collision
{
CurrentActivatedCollision = AttackNumber;
AttackCollisions[AttackNumber]->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
AttackCollisions[AttackNumber]->SetGenerateOverlapEvents(true);
}
- SetCollisionEnabled는 그대로 유지하여 계산이 필요없는 구간에서는 키고 끄도록 최적화
- 더불어 SetGenerateOverlapEvents도 함께 호출하여 이전에 계산한 데이터들을 쓸 수 없도록 설정하여 매번 업데이트
- 문제 상황 해결 완료
참고
else // Activate Collision
{
CurrentActivatedCollision = AttackNumber;
AttackCollisions[AttackNumber]->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
TArray<AActor*> OverlappingActors;
AttackCollisions[AttackNumber]->GetOverlappingActors(OverlappingActors);
for (AActor* OtherActor : OverlappingActors)
{
if (OtherActor != this)
{
OnAttackOverlap(AttackCollisions[AttackNumber], OtherActor, nullptr, 0, false, FHitResult());
}
}
UE_LOG(LogTemp,Warning,TEXT("Activate Collision! (Index: %d)"),AttackNumber);
}
- 해당 코드와 같이 GetOverlappingActors로 현재 겹쳐있는 모든 캐릭터를 직접 확인하여 바인딩했던 함수를 직접 호출하여 해결하는 것도 가능
참고자료
https://dev.epicgames.com/documentation/ko-kr/unreal-engine/events-in-unreal-engine
Overlapping not triggering on dynamic toggled collision
I have a simple test set up here. Upon overlapping with a player, the trigger on the right toggles the collision of the plane, which is a staticmesh component of a blueprint actor. The trigger on the left overlaps all and is set up to a print string upon o
forums.unrealengine.com
'프로젝트 > CCFF' 카테고리의 다른 글
미친 선인장과 분노의 버섯 - #18 프로젝트 마무리 (0) | 2025.04.18 |
---|---|
미친 선인장과 분노의 버섯 - #16 캐릭터 스테이터스와 인게임 HUD 연동 (0) | 2025.04.16 |
미친 선인장과 분노의 버섯 - #15 버퍼를 이용한 선입력(예약) & 키 조합을 통한 액션 및 상태에 따른 동작 다변화 (0) | 2025.04.15 |
미친 선인장과 분노의 버섯 - #14 더블 클릭을 통한 달리기 (0) | 2025.04.14 |
미친 선인장과 분노의 버섯 - #13 카메라 회전 트러블 슈팅 + 클라이언트 UI 상태 변화에 따른 업데이트 (0) | 2025.04.11 |