RealtimeStyleTransferRuntime/Source/LyraGame/Feedback/ContextEffects/LyraContextEffectsSubsystem...

149 lines
5.0 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "LyraContextEffectsSubsystem.h"
#include "Engine/EngineTypes.h"
#include "Feedback/ContextEffects/LyraContextEffectsLibrary.h"
#include "GameplayTagContainer.h"
#include "Kismet/GameplayStatics.h"
#include "NiagaraCommon.h"
#include "NiagaraFunctionLibrary.h"
class AActor;
class UAudioComponent;
class UNiagaraSystem;
class USceneComponent;
class USoundBase;
void ULyraContextEffectsSubsystem::SpawnContextEffects(
const AActor* SpawningActor
, USceneComponent* AttachToComponent
, const FName AttachPoint
, const FVector LocationOffset
, const FRotator RotationOffset
, FGameplayTag Effect
, FGameplayTagContainer Contexts
, TArray<UAudioComponent*>& AudioOut
, TArray<UNiagaraComponent*>& NiagaraOut
, FVector VFXScale
, float AudioVolume
, float AudioPitch)
{
// First determine if this Actor has a matching Set of Libraries
if (TObjectPtr<ULyraContextEffectsSet>* EffectsLibrariesSetPtr = ActiveActorEffectsMap.Find(SpawningActor))
{
// Validate the pointers from the Map Find
if (ULyraContextEffectsSet* EffectsLibraries = *EffectsLibrariesSetPtr)
{
// Prepare Arrays for Sounds and Niagara Systems
TArray<USoundBase*> TotalSounds;
TArray<UNiagaraSystem*> TotalNiagaraSystems;
// Cycle through Effect Libraries
for (ULyraContextEffectsLibrary* EffectLibrary : EffectsLibraries->LyraContextEffectsLibraries)
{
// Check if the Effect Library is valid and data Loaded
if (EffectLibrary && EffectLibrary->GetContextEffectsLibraryLoadState() == EContextEffectsLibraryLoadState::Loaded)
{
// Set up local list of Sounds and Niagara Systems
TArray<USoundBase*> Sounds;
TArray<UNiagaraSystem*> NiagaraSystems;
// Get Sounds and Niagara Systems
EffectLibrary->GetEffects(Effect, Contexts, Sounds, NiagaraSystems);
// Append to accumulating array
TotalSounds.Append(Sounds);
TotalNiagaraSystems.Append(NiagaraSystems);
}
else if (EffectLibrary && EffectLibrary->GetContextEffectsLibraryLoadState() == EContextEffectsLibraryLoadState::Unloaded)
{
// Else load effects
EffectLibrary->LoadEffects();
}
}
// Cycle through found Sounds
for (USoundBase* Sound : TotalSounds)
{
// Spawn Sounds Attached, add Audio Component to List of ACs
UAudioComponent* AudioComponent = UGameplayStatics::SpawnSoundAttached(Sound, AttachToComponent, AttachPoint, LocationOffset, RotationOffset, EAttachLocation::KeepRelativeOffset,
false, AudioVolume, AudioPitch, 0.0f, nullptr, nullptr, true);
AudioOut.Add(AudioComponent);
}
// Cycle through found Niagara Systems
for (UNiagaraSystem* NiagaraSystem : TotalNiagaraSystems)
{
// Spawn Niagara Systems Attached, add Niagara Component to List of NCs
UNiagaraComponent* NiagaraComponent = UNiagaraFunctionLibrary::SpawnSystemAttached(NiagaraSystem, AttachToComponent, AttachPoint, LocationOffset,
RotationOffset, VFXScale, EAttachLocation::KeepRelativeOffset, true, ENCPoolMethod::None, true, true);
NiagaraOut.Add(NiagaraComponent);
}
}
}
}
bool ULyraContextEffectsSubsystem::GetContextFromSurfaceType(
TEnumAsByte<EPhysicalSurface> PhysicalSurface, FGameplayTag& Context)
{
// Get Project Settings
if (const ULyraContextEffectsSettings* ProjectSettings = GetDefault<ULyraContextEffectsSettings>())
{
// Find which Gameplay Tag the Surface Type is mapped to
if (const FGameplayTag* GameplayTagPtr = ProjectSettings->SurfaceTypeToContextMap.Find(PhysicalSurface))
{
Context = *GameplayTagPtr;
}
}
// Return true if Context is Valid
return Context.IsValid();
}
void ULyraContextEffectsSubsystem::LoadAndAddContextEffectsLibraries(AActor* OwningActor,
TSet<TSoftObjectPtr<ULyraContextEffectsLibrary>> ContextEffectsLibraries)
{
// Early out if Owning Actor is invalid or if the associated Libraries is 0 (or less)
if (OwningActor == nullptr || ContextEffectsLibraries.Num() <= 0)
{
return;
}
// Create new Context Effect Set
ULyraContextEffectsSet* EffectsLibrariesSet = NewObject<ULyraContextEffectsSet>(this);
// Cycle through Libraries getting Soft Obj Refs
for (const TSoftObjectPtr<ULyraContextEffectsLibrary>& ContextEffectSoftObj : ContextEffectsLibraries)
{
// Load Library Assets from Soft Obj refs
// TODO Support Async Loading of Asset Data
if (ULyraContextEffectsLibrary* EffectsLibrary = ContextEffectSoftObj.LoadSynchronous())
{
// Call load on valid Libraries
EffectsLibrary->LoadEffects();
// Add new library to Set
EffectsLibrariesSet->LyraContextEffectsLibraries.Add(EffectsLibrary);
}
}
// Update Active Actor Effects Map
ActiveActorEffectsMap.Emplace(OwningActor, EffectsLibrariesSet);
}
void ULyraContextEffectsSubsystem::UnloadAndRemoveContextEffectsLibraries(AActor* OwningActor)
{
// Early out if Owning Actor is invalid
if (OwningActor == nullptr)
{
return;
}
// Remove ref from Active Actor/Effects Set Map
ActiveActorEffectsMap.Remove(OwningActor);
}