Files
UnrealEngine/Engine/Plugins/FX/Niagara/Source/NiagaraAnimNotifies/Private/AnimNotify_PlayNiagaraEffect.cpp
2025-05-18 13:04:45 +08:00

139 lines
3.8 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "AnimNotify_PlayNiagaraEffect.h"
#include "Components/SkeletalMeshComponent.h"
#include "Engine/World.h"
#if WITH_EDITOR
#include "Logging/MessageLog.h"
#include "Misc/UObjectToken.h"
#endif
#include "NiagaraComponent.h"
#include "NiagaraSystem.h"
#include "NiagaraFunctionLibrary.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(AnimNotify_PlayNiagaraEffect)
/////////////////////////////////////////////////////
// UAnimNotify_PlayNiagaraEffect
UAnimNotify_PlayNiagaraEffect::UAnimNotify_PlayNiagaraEffect()
: Super()
{
Attached = true;
Scale = FVector(1.f);
bAbsoluteScale = false;
#if WITH_EDITORONLY_DATA
NotifyColor = FColor(192, 255, 99, 255);
#endif // WITH_EDITORONLY_DATA
}
void UAnimNotify_PlayNiagaraEffect::PostLoad()
{
Super::PostLoad();
RotationOffsetQuat = FQuat(RotationOffset);
}
#if WITH_EDITOR
void UAnimNotify_PlayNiagaraEffect::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
Super::PostEditChangeProperty(PropertyChangedEvent);
if (PropertyChangedEvent.MemberProperty && PropertyChangedEvent.MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(UAnimNotify_PlayNiagaraEffect, RotationOffset))
{
RotationOffsetQuat = FQuat(RotationOffset);
}
}
void UAnimNotify_PlayNiagaraEffect::ValidateAssociatedAssets()
{
static const FName NAME_AssetCheck("AssetCheck");
if ((Template != nullptr) && (Template->IsLooping()))
{
UObject* ContainingAsset = GetContainingAsset();
FMessageLog AssetCheckLog(NAME_AssetCheck);
const FText MessageLooping = FText::Format(
NSLOCTEXT("AnimNotify", "NiagaraSystem_ShouldNotLoop", "Niagara system {0} used in anim notify for asset {1} is set to looping, but the slot is a one-shot (it won't be played to avoid leaking a component per notify)."),
FText::AsCultureInvariant(Template->GetPathName()),
FText::AsCultureInvariant(ContainingAsset->GetPathName()));
AssetCheckLog.Warning()
->AddToken(FUObjectToken::Create(ContainingAsset))
->AddToken(FTextToken::Create(MessageLooping));
if (GIsEditor)
{
AssetCheckLog.Notify(MessageLooping, EMessageSeverity::Warning, /*bForce=*/ true);
}
}
}
#endif
void UAnimNotify_PlayNiagaraEffect::Notify(class USkeletalMeshComponent* MeshComp, class UAnimSequenceBase* Animation)
{
}
void UAnimNotify_PlayNiagaraEffect::Notify(class USkeletalMeshComponent* MeshComp, class UAnimSequenceBase* Animation, const FAnimNotifyEventReference& EventReference)
{
//Store the spawned effect in a protected variable
SpawnedEffect = SpawnEffect(MeshComp, Animation);
//Call to BP to allows setting of Niagara User Variables
Super::Notify(MeshComp, Animation, EventReference);
}
FString UAnimNotify_PlayNiagaraEffect::GetNotifyName_Implementation() const
{
if (Template)
{
return Template->GetName();
}
else
{
return Super::GetNotifyName_Implementation();
}
}
UFXSystemComponent* UAnimNotify_PlayNiagaraEffect::SpawnEffect(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation)
{
UFXSystemComponent* ReturnComp = nullptr;
if (Template)
{
if (Template->IsLooping())
{
return ReturnComp;
}
if (Attached)
{
ReturnComp = UNiagaraFunctionLibrary::SpawnSystemAttached(Template, MeshComp, SocketName, LocationOffset, RotationOffset, EAttachLocation::KeepRelativeOffset, true);
}
else
{
const FTransform MeshTransform = MeshComp->GetSocketTransform(SocketName);
ReturnComp = UNiagaraFunctionLibrary::SpawnSystemAtLocation(MeshComp->GetWorld(), Template, MeshTransform.TransformPosition(LocationOffset), (MeshTransform.GetRotation() * RotationOffsetQuat).Rotator(), FVector(1.0f),true);
}
if (ReturnComp != nullptr)
{
ReturnComp->SetUsingAbsoluteScale(bAbsoluteScale);
ReturnComp->SetRelativeScale3D_Direct(Scale);
}
}
return ReturnComp;
}
UFXSystemComponent* UAnimNotify_PlayNiagaraEffect::GetSpawnedEffect()
{
return SpawnedEffect;
}