본문 바로가기

개발/언리얼

UAnimNotifyState_TimedNiagaraEffect, 트레일(궤적) 이펙트 에셋 적용

사용 에셋(개인무료!)

https://www.fab.com/listings/bd2ba790-7266-49f3-bb4f-8049f6797c01

 

Stylized Sword Trails VFX

DEMO VIDEO#Answer | How to Add Sword/Weapon Trails to a Character in UE5#Guide | How to Make Sword Trails for Games and Cinematics in UE5This asset pack provides a collection of dynamic and visually striking sword trail effects, perfect for adding an extra

www.fab.com

 

에셋 개발자가 제공하는 가이드 영상

https://www.youtube.com/live/yPghU6L-QkE

 

가이드 영상은 블루프린트인데, C++로 적용하는 겸, 추가로 런타임에서 다른 나이아가라 효과를 적용해보려 한다.

 

에셋을 다운받아 가지고있다면 설정을 몇가지 해주어야 하는데

첫번째로 스켈레톤에 소켓을 설정해주어야 한다.

검의 궤적효과는 소켓에 올라간 액터에게 적용이 되기때문에, 캐릭터가 무기를 든다면, 무기를 들려준 소켓을 사용하면 된다.

기존에 만들어두었던 소켓을 사용하겟다.

 

사용중인 캐릭터의 Skeleton에셋을 열고 소켓 이름확인.

추가방법은 원하는 스켈레톤 우클릭-Add Socket 후 프리뷰에셋 등록하여 위치 조정하기.

 

두번째로는 애니메이션 시퀀스 또는 몽타주에서 NotifyState - TimedNiagaraEffect를 추가하는것.

시퀀스에 설정하면 몽타주에 없더라도 적용되니 주의(한곳만)

해당 노티파이의 기능은 애니메이션 내에서 지정한 구간 동안 나이아가라 효과를 생성하는것.

노티가 추가되었으면 좌우의 마름모를 드래그하여 애니메이션을 보며 어디서 어디까지 재생할지 구역을 조정해야한다.

 

 

노티파이를 추가했다면 디테일 패널에서 사용할 나이아가라 효과와 소켓의 이름을 입력

강조된 두칸을 반드시 추가해야한다.

 

정상 적용되었다면 벌써 애니메이션 프리뷰에서 적용되는걸 볼 수 있다.

Hand_R_Weapon소켓과 무기액터의 Transform이 같으니 궤적이 따라오는것처럼 보이는것

 

여기까지는 간단한데, 여기서 문제는 하나의 Notify에 하나의 이펙트밖에 사용하지 못하는것이다.

이 부분을 수정하기위해 TimedNiagaraEffect 노티파이를 상속받은 C++코드를 이용할것이다.

 

C++로 상속받은 코드 생성

코드를 생성하고,

 

두가지 함수를 생성한다.

SpawnEffect()는 부모클래스의 함수를 재정의할것이다(Super쓰지말것)

Private함수인 GetWeaponTrailNiagara()는 플레이어나 무기로부터 사용할 이펙트를 가져올 함수이다.

이를 위해서 사용할 캐릭터나 무기 등에 UNiagaraSystem* 변수를 하나 미리 가지고 있어야 할것이다.

#pragma once

#include "CoreMinimal.h"
#include "AnimNotifyState_TimedNiagaraEffect.h"
#include "WeaponTrail_TimedNiagara.generated.h"

class UNiagaraSystem;
class USkeletalMeshComponent;
class UAnimSequenceBase;
class UFXSystemComponent;

UCLASS()
class CLAMOR_LIBERTATIS_API UWeaponTrail_TimedNiagara : public UAnimNotifyState_TimedNiagaraEffect
{
	GENERATED_BODY()
public:
	UWeaponTrail_TimedNiagara();

protected:
	virtual UFXSystemComponent* SpawnEffect(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation) const override;

private:
	UNiagaraSystem* GetWeaponTrailNiagara(USkeletalMeshComponent* MeshComp) const;
};

 

구현부로 넘어와서,

생성자에서는 SocketName에 값을 넣어두도록한다. 이는 부모클래스에서 가지고있는 변수이고, 생성시 해당 소켓을 사용.

UWeaponTrail_TimedNiagara::UWeaponTrail_TimedNiagara()
{
	SocketName = TEXT("Hand_R_Weapon");
	bDestroyAtEnd = false;
}

 

 

우선 플레이어(호출한 액터)로부터 나이아가라 시스템을 가져오는것부터 작성

따라하는 사람이 있다면 자신의 코드에 맞출것.

UNiagaraSystem* UWeaponTrail_TimedNiagara::GetWeaponTrailNiagara(USkeletalMeshComponent* MeshComp) const
{
	if (!MeshComp)
	{
		return nullptr;
	}

	AActor* OwnerActor = MeshComp->GetOwner();
	if (!OwnerActor)
	{
		return nullptr;
	}

	const UCombatComponent* CombatComponent = OwnerActor->FindComponentByClass<UCombatComponent>();
	if (!CombatComponent)
	{
		return nullptr;
	}

	const AWeaponBase* CurrentWeapon = CombatComponent->GetCurrentWeapon();
	return CurrentWeapon ? CurrentWeapon->GetWeaponTrailNiagara() : nullptr;
}

호출시에 USkeletalMeshComponent* MeshComp를 인자로 받는데 이는 효과가 적용될 액터의 메시컴포넌트이다.

내 경우 이는 무기의 메시가 될것이고, 이 메시의 주인 액터는 플레이어 캐릭터이다.

그러니 MeshComp->GetOwner()를 통해 플레이어 캐릭터를 가져올 수 있다.

 

그래서 플레이어캐릭터의 무기를 가져오고, 무기 클래스로부터 NiagaraSystem을 가져오도록 하였다.

추가로 설명하자면, 내 코드의 경우 무기마다 궤적 효과 NiagaraSystem을 가지고 있고 이에 대한 Getter/Setter를 만들어두었다.

이를 통해 NiagaraSystem가져오고 호출자에게 반환한다.

 

다음으로 SpawnEffect를 재정의한 함수

UFXSystemComponent* UWeaponTrail_TimedNiagara::SpawnEffect(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation) const
{
	UNiagaraSystem* NiagaraTemplate = GetWeaponTrailNiagara(MeshComp);
	if (!NiagaraTemplate)
	{
		NiagaraTemplate = Template;
	}

	if (!MeshComp || !NiagaraTemplate)
	{
		return nullptr;
	}

	UNiagaraComponent* NiagaraComponent = UNiagaraFunctionLibrary::SpawnSystemAttached(
		NiagaraTemplate,
		MeshComp,
		SocketName,
		LocationOffset,
		RotationOffset,
		EAttachLocation::KeepRelativeOffset,
		true,
		true,
		ENCPoolMethod::None,
		true
	);

	if (NiagaraComponent)
	{
		if (bApplyRateScaleAsTimeDilation && Animation)
		{
			NiagaraComponent->SetCustomTimeDilation(Animation->RateScale);
		}
	}

	return NiagaraComponent;
}

아까 정의한 함수로부터 UNiagaraSystem*을 가져온다.

없다면, 기본설정된 값인 Template를 사용하도록 한다.(에디터에서 설정한 효과가 Templete변수에있음!)

 

UNiagaraFunctionLibrary::SpawnSystemAttached()함수를 통해 효과를 생성 및  무기에 부착하고, 자동 제거되도록 설정한다

 

생성된 컴포넌트의 재생속도를 호출한 애니메이션의 속도와 동일하게 설정하여, 두개가 맞도록 해준다.

생성된 컴포넌트를 반환해주면 엔진에서 자체적으로 관리하기때문에 생성 및 제거를 추가로 해줄 필요가 없다.

 

이렇게 커스텀한 나의  TimedNiagaraEffect가 생겼으니 

기존에 있던 엔진 기본 TimedNiagaraEffect를 내가 생성한 노티파이로 교체한다.

디테일 패널은 기본값을 설정해주면 된다.

무기등 다른곳에서 효과데이터가 없을경우의 기본값을 넣어준다고 생각하면 된다.

 

노티파이를 교체하면 끝