0. 개요

이전 포스트에서 투사체를 목표에 정렬시키는 작업을 했다.

이번 포스트에서는 투사체에 액터 혹은 사물에 적중하는 효과를 준다.

 

 

1. 나이아가라 시스템(Niagara System)

파티클을 이용한 이펙트를 관리하는 시스템이다.

 

(1) 종속성 추가 - Aura.Build.cs

public class Aura : ModuleRules
{
	public Aura(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
	
		PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "EnhancedInput", "GameplayAbilities", "UMG" });

		PrivateDependencyModuleNames.AddRange(new string[] { "GameplayTags", "GameplayTasks", "NavigationSystem", "Niagara" });

 

 

2. 투사체 적중 시 효과 재생 - AuraProjectile

private:
	bool bHit = false;

	UPROPERTY(VisibleAnywhere)
	TObjectPtr<USphereComponent> Sphere;

	UPROPERTY(EditAnywhere)
	TObjectPtr<UNiagaraSystem> ImpactEffect;

	UPROPERTY(EditAnywhere)
	TObjectPtr<USoundBase> ImpactSound;
};

적중 시 효과와 적중을 판단하는 불리언을 선언한다.

아래의 헤더파일을 첨부한다.

#include "Kismet/GameplayStatics.h"
#include "NiagaraFunctionLibrary.h"
void AAuraProjectile::OnSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	UGameplayStatics::PlaySoundAtLocation(this, ImpactSound, GetActorLocation(), FRotator::ZeroRotator);
	UNiagaraFunctionLibrary::SpawnSystemAtLocation(this, ImpactEffect, GetActorLocation());

	if (HasAuthority())
	{
		Destroy();
	}
	else
	{
		bHit = true;
	}
}

투사체의 구체가 겹칠때 소리와 이펙트를 실행한다.

서버 측이라면 투사체를 파괴한다.

클라이언트 측이라면 불리언을 true로 바꾼다.

 

클라이언트는 투사체를 생성하고 파괴할 권한이 없다. 투사체를 생성하고 파괴하는 것은 오직 서버에서만 판단한다.

클라이언트에서 소리와 이펙트를 재생하기 위해서는 서버의 Destroy를 기다리는 Destroyed 함수를 오버라이드하여 사용한다.

protected:
	virtual void BeginPlay() override;

	virtual void Destroyed() override;
void AAuraProjectile::Destroyed()
{
	// 클라이언트
	if (!bHit && !HasAuthority())
	{
		UGameplayStatics::PlaySoundAtLocation(this, ImpactSound, GetActorLocation(), FRotator::ZeroRotator);
		UNiagaraFunctionLibrary::SpawnSystemAtLocation(this, ImpactEffect, GetActorLocation());
	}
	Super::Destroyed();
}

클라이언트에서는 소리와 이펙트가 재생된 뒤에 제거가 완료되어야 하므로 Super의 Destroyed 함수를 마지막에 호출한다.

 

 

3. 몽타주에서 효과 재생 - AM_Cast_FireBolt

노티파이를 이용하여 파이어볼트가 생성될 때 소리를 재생하도록 한다.

새로운 노티파이 트랙인 Sound를 만들고 사운드 재생 노티파이를 생성한다.

디테일 창에서 사운드를 설정한다.

 

 

4. 투사체에 반복되는 소리 효과 추가

파이어볼트 투사체에 타들어가는 소리를 추가할 것이다.

	UPROPERTY(EditAnywhere)
	TObjectPtr<USoundBase> LoopingSound;

	UPROPERTY()
	TObjectPtr<UAudioComponent> LoopingSoundComponent;
void AAuraProjectile::BeginPlay()
{
	Super::BeginPlay();

	Sphere->OnComponentBeginOverlap.AddDynamic(this, &AAuraProjectile::OnSphereOverlap);
	
	LoopingSoundComponent = UGameplayStatics::SpawnSoundAttached(LoopingSound, GetRootComponent());
}

SpawnSoundAttached 함수를 사용하여 액터에 존재하지 않는 컴포넌트를 붙여, 이후에 소리를 멈추게 할 수 있다.

해당 컴포넌트를 로컬 변수로 저장하여 추후에 정지시키도록 한다.

void AAuraProjectile::Destroyed()
{
	// 클라이언트
	if (!bHit && !HasAuthority())
	{
		UGameplayStatics::PlaySoundAtLocation(this, ImpactSound, GetActorLocation(), FRotator::ZeroRotator);
		UNiagaraFunctionLibrary::SpawnSystemAtLocation(this, ImpactEffect, GetActorLocation());
		LoopingSoundComponent->Stop();
	}
	Super::Destroyed();
}

void AAuraProjectile::OnSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	UGameplayStatics::PlaySoundAtLocation(this, ImpactSound, GetActorLocation(), FRotator::ZeroRotator);
	UNiagaraFunctionLibrary::SpawnSystemAtLocation(this, ImpactEffect, GetActorLocation());
	LoopingSoundComponent->Stop();

 

 

5. 투사체에 수명 설정

투사체가 일정 시간을 체공하면 제거되도록 설정할 것이다.

private:
	UPROPERTY(EditDefaultsOnly)
	float LifeSpan = 15.f;
void AAuraProjectile::BeginPlay()
{
	Super::BeginPlay();
	SetLifeSpan(LifeSpan);