01.02 - TIL

김혁·2026년 1월 2일

TIL

목록 보기
84/84
post-thumbnail

팀 프로젝트 진행 내용

1. 레벨 이동 중 어빌리티 오류 수정

LogWindows: Error: === Critical error: ===
LogWindows: Error: 
LogWindows: Error: Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0x00000000000000d8
LogWindows: Error: 
LogWindows: Error: [Callstack] 0x00007ff6640621ee AO.exe!UAO_GameplayAbility_Sprint::CanActivateAbility() [C:\Users\User\Desktop\3rd_4th-Team4-CH6-Project\Source\AO\Private\Character\GAS\Ability\AO_GameplayAbility_Sprint.cpp:44]
LogWindows: Error: [Callstack] 0x00007ff663cae8e3 AO.exe!UAbilitySystemComponent::InternalTryActivateAbility() []
LogWindows: Error: [Callstack] 0x00007ff663cd0329 AO.exe!UAbilitySystemComponent::TryActivateAbility() []
LogWindows: Error: [Callstack] 0x00007ff6640f14ba AO.exe!AAO_PlayerCharacter::HandleGameplayAbilityInputPressed() [C:\Users\User\Desktop\3rd_4th-Team4-CH6-Project\Source\AO\Private\Character\AO_PlayerCharacter.cpp:475]
LogWindows: Error: [Callstack] 0x00007ff6640f0bf9 AO.exe!TBaseUObjectMethodDelegateInstance<0,AAO_PlayerCharacter,void __cdecl(void),FDefaultDelegateUserPolicy,int>::Execute() [C:\Program Files\Epic Games\UE_5.6\Engine\Source\Runtime\Core\Public\Delegates\DelegateInstancesImpl.h:673]
LogWindows: Error: [Callstack] 0x00007ff66406f054 AO.exe!FEnhancedInputActionEventDelegateBinding<TDelegate<void __cdecl(void),FDefaultDelegateUserPolicy> >::Execute() [C:\Program Files\Epic Games\UE_5.6\Engine\Plugins\EnhancedInput\Source\EnhancedInput\Public\EnhancedInputComponent.h:321]
LogWindows: Error: [Callstack] 0x00007ff663f45599 AO.exe!UEnhancedPlayerInput::EvaluateInputDelegates() []
LogWindows: Error: [Callstack] 0x00007ff66238774a AO.exe!UPlayerInput::ProcessInputStack() []
LogWindows: Error: [Callstack] 0x00007ff661cc3878 AO.exe!APlayerController::ProcessPlayerInput() []
LogWindows: Error: [Callstack] 0x00007ff661cdd58f AO.exe!APlayerController::TickPlayerInput() []
LogWindows: Error: [Callstack] 0x00007ff661cc0dea AO.exe!APlayerController::PlayerTick() []
LogWindows: Error: [Callstack] 0x00007ff661cdb917 AO.exe!APlayerController::TickActor() []
LogWindows: Error: [Callstack] 0x00007ff660ac33fe AO.exe!FActorTickFunction::ExecuteTick() []
LogWindows: Error: [Callstack] 0x00007ff6622a86c9 AO.exe!FTickFunctionTask::DoTask() []
LogWindows: Error: [Callstack] 0x00007ff6622adc72 AO.exe!TGraphTask<FTickFunctionTask>::ExecuteTask() []
LogWindows: Error: [Callstack] 0x00007ff65a1b53f3 AO.exe!UE::Tasks::Private::FTaskBase::TryExecuteTask() []
LogWindows: Error: [Callstack] 0x00007ff65a1a82e9 AO.exe!FNamedTaskThread::ProcessTasksNamedThread() []
LogWindows: Error: [Callstack] 0x00007ff65a1a86d9 AO.exe!FNamedTaskThread::ProcessTasksUntilIdle() []
LogWindows: Error: [Callstack] 0x00007ff65a1a8e15 AO.exe!FTaskGraphCompatibilityImplementation::ProcessUntilTasksComplete() []
LogWindows: Error: [Callstack] 0x00007ff6622c860c AO.exe!FTickTaskSequencer::ReleaseTickGroup() []
LogWindows: Error: [Callstack] 0x00007ff6622cfe9f AO.exe!FTickTaskManager::RunTickGroup() []
LogWindows: Error: [Callstack] 0x00007ff66178ffbe AO.exe!UWorld::RunTickGroup() []
LogWindows: Error: [Callstack] 0x00007ff661798ba8 AO.exe!UWorld::Tick() []
LogWindows: Error: [Callstack] 0x00007ff6614608f6 AO.exe!UGameEngine::Tick() []
LogWindows: Error: [Callstack] 0x00007ff66281e7b1 AO.exe!FEngineLoop::Tick() []
LogWindows: Error: [Callstack] 0x00007ff662831f0c AO.exe!GuardedMain() []
LogWindows: Error: [Callstack] 0x00007ff662831fea AO.exe!GuardedMainWrapper() []
LogWindows: Error: [Callstack] 0x00007ff662834e18 AO.exe!LaunchWindowsStartup() []
LogWindows: Error: [Callstack] 0x00007ff662842414 AO.exe!WinMain() []
LogWindows: Error: [Callstack] 0x00007ff6697044da AO.exe!__scrt_common_main_seh() [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288]
LogWindows: Error: [Callstack] 0x00007fff4303e8d7 KERNEL32.DLL!UnknownFunction []
  • 테스트 중에 위와 같은 에러 로그와 함께 크래시가 발생했다.
  • 레벨 전환 중에서 해당 크래시가 발생했는데, CanActivateAbility()에서 null 값에 접근해서 발생한 오류인 것으로 보였다.
// AO_GameplayAbility_Sprint.cpp

bool UAO_GameplayAbility_Sprint::CanActivateAbility(const FGameplayAbilitySpecHandle Handle,
                                                    const FGameplayAbilityActorInfo* ActorInfo, const FGameplayTagContainer* SourceTags,
                                                    const FGameplayTagContainer* TargetTags, FGameplayTagContainer* OptionalRelevantTags) const
{
	if (!Super::CanActivateAbility(Handle, ActorInfo, SourceTags, TargetTags, OptionalRelevantTags))
	{
		return false;
	}

	if (CharacterMovement->Velocity.SizeSquared2D() < KINDA_SMALL_NUMBER)
	{
		return false;
	}

	if (CharacterMovement->IsCrouching())
	{
		return false;
	}

	const UAO_PlayerCharacter_AttributeSet* AttributeSet = ActorInfo->AbilitySystemComponent->GetSetChecked<UAO_PlayerCharacter_AttributeSet>();
	const float CurrentStamina = AttributeSet->GetStamina();
	const float MaxStamina = AttributeSet->GetMaxStamina();

	if (CurrentStamina < MaxStamina * AttributeSet->StaminaLockoutPercent)
	{
		return false;
	}

	return true;
}
  • Sprint 어빌리티의 경우에는 플레이어의 입력에 따라 즉각적으로 실행되는 어빌리티인데, 레벨 전환 간에 캐싱해놓은 CharacterMovement에 접근하다 보니 해당 오류가 발생한 것으로 보인다.
  • 기존의 GA 인스턴스가 남아있는데, 캐릭터가 파괴되는 타이밍이 빨라서 CharacterMovement에 접근해서 크래시가 발생한 것이지 않을까 생각했다.
  • Sprint의 경우에는 자주 사용하게 되어서 Ability 차원에서 CharacterCharacterMovement를 캐싱해놓는데, 이 구조가 수명주기가 흔들리는 순간에 상당히 취약해보여서 해당 부분을 캐싱해놓는 구조가 아니라 매번 가져오는 것으로 수정했다.
// AO_GameplayAbility_Sprint.cpp

// void UAO_GameplayAbility_Sprint::OnAvatarSet(const FGameplayAbilityActorInfo* ActorInfo,
// 	  const FGameplayAbilitySpec& Spec)
// {
// 	   Super::OnAvatarSet(ActorInfo, Spec);
//    
// 	   Character = Cast<AAO_PlayerCharacter>(ActorInfo->AvatarActor.Get());
// 	   checkf(Character, TEXT("Failed to cast AvatarActor to ACharacter"));
//    
// 	   CharacterMovement = Character->GetCharacterMovement();
// 	   checkf(CharacterMovement, TEXT("Failed to get CharacterMovementComponent"));
// }

bool UAO_GameplayAbility_Sprint::CanActivateAbility(const FGameplayAbilitySpecHandle Handle,
                                                    const FGameplayAbilityActorInfo* ActorInfo, const FGameplayTagContainer* SourceTags,
                                                    const FGameplayTagContainer* TargetTags, FGameplayTagContainer* OptionalRelevantTags) const
{
	if (!Super::CanActivateAbility(Handle, ActorInfo, SourceTags, TargetTags, OptionalRelevantTags))
	{
		return false;
	}

	if (!ActorInfo || !ActorInfo->AbilitySystemComponent.IsValid() || !ActorInfo->AvatarActor.IsValid())
	{
		return false;
	}

	const AAO_PlayerCharacter* Character = Cast<AAO_PlayerCharacter>(ActorInfo->AvatarActor.Get());
	if (!Character)
	{
		return false;
	}

	const UCharacterMovementComponent* CharacterMovement = Character->GetCharacterMovement();
	if (!CharacterMovement)
	{
		return false;
	}
    
    ...
}

profile
게임 개발자를 향해..

0개의 댓글