UE 5 스터디/Gameplay Ability System(GAS)

32-13. 로그 라이크 - (6) 보스 - (3) 보스 속성 개선, 공격력 개선, 스펠 개선

Crat3 2025. 6. 19. 18:39

 

1. 보스 체력 및 기본 속성(Attributes) 개선

기존에 각 캐릭터 블루프린트의 Attribute Gameplay Effects를 지정해도 반영이 되지 않는 버그가 있었는데, 이는 캐릭터 클래스 인포 데이터 에셋을 참조해서 공용 게임플레이 이펙트를 공유하기 때문이었다. 따라서 아래 부분을 변경한다.

void UAuraAbilitySystemLibrary::InitializeDefaultAttributes(const UObject* WorldContextObject, ECharacterClass CharacterClass, float Level, UAbilitySystemComponent* ASC)
{
	AActor* AvatarActor = ASC->GetAvatarActor();
	AAuraCharacterBase* AvatarCharacter = Cast<AAuraCharacterBase>(AvatarActor);
	
	// 액터의 클래스 정보 가져오기
	UCharacterClassInfo* CharacterClassInfo = GetCharacterClassInfo(AvatarActor);
	if (CharacterClassInfo == nullptr)
		return;

	FCharacterClassDefaultInfo ClassDefaultInfo = CharacterClassInfo->GetClassDefaultInfo(CharacterClass);

	

	// 이펙트 스펙을 위한 컨텍스트 핸들 생성
	FGameplayEffectContextHandle PrimaryAttributesContextHandle = ASC->MakeEffectContext();
	PrimaryAttributesContextHandle.AddSourceObject(AvatarActor);

	FGameplayEffectContextHandle SecondaryAttributesContextHandle = ASC->MakeEffectContext();
	SecondaryAttributesContextHandle.AddSourceObject(AvatarActor);

	FGameplayEffectContextHandle VitalAttributesContextHandle = ASC->MakeEffectContext();
	VitalAttributesContextHandle.AddSourceObject(AvatarActor);

	// 이펙트 적용을 위한 이펙트 스펙 생성 후 적용 - ClassClassInfo가 아닌 클래스 디폴트를 참조하도록 수정됨
	const FGameplayEffectSpecHandle PrimaryAttributesSpecHandle = ASC->MakeOutgoingSpec(AvatarCharacter->DefaultPrimaryAttributes, Level, PrimaryAttributesContextHandle);
	ASC->ApplyGameplayEffectSpecToSelf(*PrimaryAttributesSpecHandle.Data.Get());

	const FGameplayEffectSpecHandle SecondaryAttributesSpecHandle = ASC->MakeOutgoingSpec(AvatarCharacter->DefaultSecondaryAttributes, Level, SecondaryAttributesContextHandle);
	ASC->ApplyGameplayEffectSpecToSelf(*SecondaryAttributesSpecHandle.Data.Get());

	const FGameplayEffectSpecHandle VitalAttributesSpecHandle = ASC->MakeOutgoingSpec(CharacterClassInfo->VitalAttributes, Level, VitalAttributesContextHandle);
	ASC->ApplyGameplayEffectSpecToSelf(*VitalAttributesSpecHandle.Data.Get());
}

이후 보스 전용 PrimaryAttributes 와 SecondaryAttributes 게임플레이 이펙트를 만들어 클래스 디폴트에 세팅한다.

 

 

 

2. 보스 공격력 개선

(1) GE_SecondaryAttributes_Boss_Shaman에서 마법 공격력 계산

 

 

 

(2) GA_EnemyFirebolt / GA_EnemyArcaneShards에 마법 공격력 계수 할당

 

 

 

3. 보스 소환 스펠 개선

보스가 소환수를 소환할 때 플레이어가 맵 끝에 있으면, 공중에 소환수를 소환하게 되어 맵 밖에 소환이 되는 버그가 있다.

TArray<FVector> UAuraSummonAbility::GetSpawnLocations()
{
	const FVector Forward = GetAvatarActorFromActorInfo()->GetActorForwardVector();
	const FVector Location = GetAvatarActorFromActorInfo()->GetActorLocation();

	int Attempt = 0;
	
	const float DeltaSpread = SpawnSpread / NumMinions;
	const FVector LeftSpread = Forward.RotateAngleAxis(-SpawnSpread / 2, FVector::UpVector);
	TArray<FVector> SpawnLocations;

	int idx = 0;
	
	while ( idx < NumMinions )
	{
		const FVector Direction = LeftSpread.RotateAngleAxis(DeltaSpread * idx, FVector::UpVector);
		FVector DirectionVector = Direction * FMath::FRandRange(MinSpawnDistance, MaxSpawnDistance - 50.f * Attempt);
		FVector ChosenSpawnLocation = Location + DirectionVector;

		FHitResult Hit;
			
		if (GetWorld()->LineTraceSingleByChannel(Hit, ChosenSpawnLocation + FVector(0.f, 0.f, 400.f), ChosenSpawnLocation - FVector(0.f, 0.f, 400.f), ECC_Visibility))
		{
			if (Hit.bBlockingHit)
			{
				ChosenSpawnLocation = Hit.ImpactPoint;
				SpawnLocations.Add(ChosenSpawnLocation);
				idx++;
			}
		}
			
		Attempt ++;

		if (Attempt > 15)
			break;
	}
	return SpawnLocations;
}

기존의 for 루프를 while 루프로 대체하고, 라인 트레이스의 불리언 값을 이용해 충돌이 실패했을 때 다시 값을 뽑고, 최대 소환 거리에서 50 * 시도 횟수 만큼의 거리를 빼어 라인 트레이스를 다시 계산한다.