Files
UnrealEngine/Engine/Plugins/FX/Niagara/Source/NiagaraEditor/Private/NiagaraParameterDefinitions.cpp
Brandyn / Techy fcc1b09210 init
2026-04-04 15:40:51 -05:00

286 lines
12 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "NiagaraParameterDefinitions.h"
#include "ScopedTransaction.h"
#include "NiagaraEditorModule.h"
#include "NiagaraEditorUtilities.h"
#include "NiagaraScriptVariable.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(NiagaraParameterDefinitions)
#define LOCTEXT_NAMESPACE "NiagaraParameterDefinitions"
UNiagaraParameterDefinitions::UNiagaraParameterDefinitions(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
bPromoteToTopInAddMenus = false;
MenuSortOrder = 100;
if (UniqueId.IsValid() == false)
{
UniqueId = FGuid::NewGuid();
}
}
UNiagaraParameterDefinitions::~UNiagaraParameterDefinitions()
{
for (FParameterDefinitionsBindingNameSubscription& Subscription : ExternalParameterDefinitionsSubscriptions)
{
Subscription.SubscribedParameterDefinitions->GetOnParameterDefinitionsChanged().RemoveAll(this);
}
}
void UNiagaraParameterDefinitions::PostLoad()
{
Super::PostLoad();
if (HasAnyFlags(RF_ClassDefaultObject) == false && GetPackage() != GetTransientPackage())
{
FNiagaraEditorModule::Get().EnsureReservedDefinitionUnique(UniqueId);
SynchronizeWithSubscribedParameterDefinitions();
}
}
void UNiagaraParameterDefinitions::PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent)
{
Super::PostEditChangeProperty(PropertyChangedEvent);
OnParameterDefinitionsChangedDelegate.Broadcast();
}
void UNiagaraParameterDefinitions::AddParameter(const FNiagaraVariable& NewVariable)
{
FScopedTransaction AddTransaction(LOCTEXT("AddParameter", "Add Parameter"));
Modify();
TObjectPtr<UNiagaraScriptVariable>& NewScriptVariable = ScriptVariables.Add_GetRef(NewObject<UNiagaraScriptVariable>(this, FName(), RF_Transactional));
NewScriptVariable->Init(NewVariable, FNiagaraVariableMetaData());
NewScriptVariable->SetIsStaticSwitch(false);
NewScriptVariable->SetIsSubscribedToParameterDefinitions(true);
NotifyParameterDefinitionsChanged();
}
bool UNiagaraParameterDefinitions::HasParameter(const FNiagaraVariable& Variable)
{
TObjectPtr<UNiagaraScriptVariable>* NewScriptVariable = ScriptVariables.FindByPredicate([Variable](TObjectPtr<UNiagaraScriptVariable> ScriptVariable)
{
return ScriptVariable->Variable == Variable;
});
return NewScriptVariable != nullptr;
}
void UNiagaraParameterDefinitions::FindOrAddParameter(const FNiagaraVariable& Variable)
{
TObjectPtr<UNiagaraScriptVariable>* NewScriptVariable = ScriptVariables.FindByPredicate([Variable](TObjectPtr<UNiagaraScriptVariable> ScriptVariable)
{
return ScriptVariable->Variable == Variable;
});
if(NewScriptVariable == nullptr)
{
AddParameter(Variable);
}
}
void UNiagaraParameterDefinitions::RemoveParameter(const FNiagaraVariable& VariableToRemove)
{
const int32 Idx = ScriptVariables.IndexOfByPredicate([&VariableToRemove](const UNiagaraScriptVariable* ScriptVariable){ return ScriptVariable->Variable == VariableToRemove; });
if (Idx != INDEX_NONE)
{
Modify();
const FGuid RemovedScriptVarGuid = ScriptVariables[Idx]->Metadata.GetVariableGuid();
// Make sure to remove any links to binding name subscriptions to external parameter libraries.
UnsubscribeBindingNameFromExternalParameterDefinitions(RemovedScriptVarGuid);
ScriptVariables.RemoveAtSwap(Idx, EAllowShrinking::No);
NotifyParameterDefinitionsChanged();
}
}
void UNiagaraParameterDefinitions::RenameParameter(const FNiagaraVariable& VariableToRename, const FName NewName)
{
if (TObjectPtr<UNiagaraScriptVariable>* ScriptVariablePtr = ScriptVariables.FindByPredicate([&VariableToRename](const UNiagaraScriptVariable* ScriptVariable) { return ScriptVariable->Variable == VariableToRename; }))
{
const FNiagaraVariable OldVariable = VariableToRename;
Modify();
UNiagaraScriptVariable* ScriptVariable = *ScriptVariablePtr;
ScriptVariable->Modify();
ScriptVariable->Variable.SetName(NewName);
ScriptVariable->UpdateChangeId();
NotifyParameterDefinitionsChanged();
}
}
const TArray<UNiagaraScriptVariable*>& UNiagaraParameterDefinitions::GetParametersConst() const
{
return ScriptVariables;
}
int32 UNiagaraParameterDefinitions::GetChangeIdHash() const
{
int32 ChangeIdHash = 0;
for (const UNiagaraScriptVariable* ScriptVar : ScriptVariables)
{
ChangeIdHash = HashCombine(ChangeIdHash, GetTypeHash(ScriptVar->GetChangeId()));
}
return ChangeIdHash;
}
TSet<FGuid> UNiagaraParameterDefinitions::GetParameterIds() const
{
TSet<FGuid> OutParameterIds;
OutParameterIds.Reserve(ScriptVariables.Num());
for (const UNiagaraScriptVariable* ScriptVariable : ScriptVariables)
{
OutParameterIds.Add(ScriptVariable->Metadata.GetVariableGuid());
}
return OutParameterIds;
}
UNiagaraScriptVariable* UNiagaraParameterDefinitions::GetScriptVariable(const FNiagaraVariable& Var)
{
if (TObjectPtr<UNiagaraScriptVariable> const* ScriptVarPtr = ScriptVariables.FindByPredicate([Var](const UNiagaraScriptVariable* ScriptVar) { return ScriptVar->Variable == Var; }))
{
return *ScriptVarPtr;
}
return nullptr;
}
UNiagaraScriptVariable* UNiagaraParameterDefinitions::GetScriptVariable(const FGuid& ScriptVarId)
{
if (TObjectPtr<UNiagaraScriptVariable> const* ScriptVarPtr = ScriptVariables.FindByPredicate([ScriptVarId](const UNiagaraScriptVariable* ScriptVar) { return ScriptVar->Metadata.GetVariableGuid() == ScriptVarId; }))
{
return *ScriptVarPtr;
}
return nullptr;
}
void UNiagaraParameterDefinitions::SubscribeBindingNameToExternalParameterDefinitions(UNiagaraParameterDefinitions* NewParameterDefinitions, const FGuid& ExternalScriptVarId, const FGuid& InternalScriptVarId)
{
FParameterDefinitionsBindingNameSubscription* LibrarySubscription = ExternalParameterDefinitionsSubscriptions.FindByPredicate([NewParameterDefinitions](const FParameterDefinitionsBindingNameSubscription& Subscription) { return Subscription.SubscribedParameterDefinitions->GetUniqueID() == NewParameterDefinitions->GetUniqueID(); });
if (!LibrarySubscription)
{
FParameterDefinitionsBindingNameSubscription& NewLibrarySubscription = ExternalParameterDefinitionsSubscriptions.AddDefaulted_GetRef();
NewLibrarySubscription.SubscribedParameterDefinitions = NewParameterDefinitions;
LibrarySubscription = &NewLibrarySubscription;
}
FScriptVarBindingNameSubscription* BindingNameSubscription = LibrarySubscription->BindingNameSubscriptions.FindByPredicate([&ExternalScriptVarId](const FScriptVarBindingNameSubscription& Subscription){ return Subscription.ExternalScriptVarId == ExternalScriptVarId; });
if (!BindingNameSubscription)
{
FScriptVarBindingNameSubscription& NewBindingNameSubscription = LibrarySubscription->BindingNameSubscriptions.AddDefaulted_GetRef();
NewBindingNameSubscription.ExternalScriptVarId = ExternalScriptVarId;
BindingNameSubscription = &NewBindingNameSubscription;
}
if (ensureMsgf(BindingNameSubscription->InternalScriptVarIds.Contains(InternalScriptVarId) == false, TEXT("Tried to add internal script var key that was already linked!")))
{
BindingNameSubscription->InternalScriptVarIds.Add(InternalScriptVarId);
}
}
void UNiagaraParameterDefinitions::UnsubscribeBindingNameFromExternalParameterDefinitions(const FGuid& InternalScriptVarToUnsubscribeId)
{
for (FParameterDefinitionsBindingNameSubscription& LibrarySubscription : ExternalParameterDefinitionsSubscriptions)
{
for (FScriptVarBindingNameSubscription& BindingNameSubscription : LibrarySubscription.BindingNameSubscriptions)
{
BindingNameSubscription.InternalScriptVarIds.Remove(InternalScriptVarToUnsubscribeId);
}
}
}
void UNiagaraParameterDefinitions::SynchronizeWithSubscribedParameterDefinitions()
{
for (int32 LibraryIdx = ExternalParameterDefinitionsSubscriptions.Num() - 1; LibraryIdx > -1; --LibraryIdx)
{
FParameterDefinitionsBindingNameSubscription& LibrarySubscription = ExternalParameterDefinitionsSubscriptions[LibraryIdx];
if (LibrarySubscription.SubscribedParameterDefinitions == nullptr)
{
ExternalParameterDefinitionsSubscriptions.RemoveAt(LibraryIdx);
continue;
}
for (int32 BindingIdx = LibrarySubscription.BindingNameSubscriptions.Num() - 1; BindingIdx > -1; --BindingIdx)
{
const FScriptVarBindingNameSubscription& BindingNameSubscription = LibrarySubscription.BindingNameSubscriptions[BindingIdx];
const FGuid& ExternalScriptVarId = BindingNameSubscription.ExternalScriptVarId;
if (const UNiagaraScriptVariable* ExternalScriptVar = LibrarySubscription.SubscribedParameterDefinitions->GetScriptVariable(ExternalScriptVarId))
{
const FGuid& ExternalScriptVarChangeId = ExternalScriptVar->GetChangeId();
const FName& ExternalScriptVarName = ExternalScriptVar->Variable.GetName();
for (const FGuid& InternalScriptVarId : BindingNameSubscription.InternalScriptVarIds)
{
if (TObjectPtr<UNiagaraScriptVariable> const* ScriptVarPtr = ScriptVariables.FindByPredicate([&InternalScriptVarId](const UNiagaraScriptVariable* ScriptVar) { return ScriptVar->Metadata.GetVariableGuid() == InternalScriptVarId; }))
{
UNiagaraScriptVariable* ScriptVar = *ScriptVarPtr;
if (ScriptVar->GetChangeId() != ExternalScriptVarChangeId)
{
ScriptVar->DefaultBinding.SetName(ExternalScriptVarName);
ScriptVar->SetChangeId(ExternalScriptVarChangeId);
NotifyParameterDefinitionsChanged();
}
}
else
{
ensureMsgf(false, TEXT("Failed to find script variable with matching key to subscriptions list! Deleted a parameter without deleting the subscription record!"));
}
}
}
else
{
// Did not find external script var in the external parameter libraries script variables; it has been deleted since last synchronization. Remove this subscription record.
LibrarySubscription.BindingNameSubscriptions.RemoveAt(BindingIdx);
if (LibrarySubscription.BindingNameSubscriptions.Num() == 0)
{
ExternalParameterDefinitionsSubscriptions.RemoveAt(LibraryIdx);
}
}
}
}
}
TArray<UNiagaraParameterDefinitions*> UNiagaraParameterDefinitions::GetAvailableParameterDefinitions(bool bSkipSubscribedParameterDefinitions) const
{
const TArray<UNiagaraParameterDefinitions*> SubscribedParameterDefinitions = bSkipSubscribedParameterDefinitions ? GetSubscribedParameterDefinitions() : TArray<UNiagaraParameterDefinitions*>();
auto GetParameterDefinitionsIsSubscribed = [&SubscribedParameterDefinitions](const UNiagaraParameterDefinitions* ParameterDefinitions)->bool {
return SubscribedParameterDefinitions.ContainsByPredicate([&ParameterDefinitions](const UNiagaraParameterDefinitions* SubscribedParameterDefinitions) { return ParameterDefinitions->GetDefinitionsUniqueId() == SubscribedParameterDefinitions->GetDefinitionsUniqueId(); });
};
TArray<FAssetData> ParameterDefinitionsAssetData;
TArray<UNiagaraParameterDefinitions*> AvailableParameterDefinitions;
TArray<FString> ExternalPackagePaths = { GetPackage()->GetOutermost()->GetPathName() };
ensureMsgf(FNiagaraEditorUtilities::GetAvailableParameterDefinitions(ExternalPackagePaths, ParameterDefinitionsAssetData), TEXT("Failed to get parameter libraries!"));
for (const FAssetData& ParameterDefinitionsAssetDatum : ParameterDefinitionsAssetData)
{
UNiagaraParameterDefinitions* ParameterDefinitions = Cast<UNiagaraParameterDefinitions>(ParameterDefinitionsAssetDatum.GetAsset());
if (ParameterDefinitions == nullptr)
{
continue;
}
else if (bSkipSubscribedParameterDefinitions && GetParameterDefinitionsIsSubscribed(ParameterDefinitions))
{
continue;
}
AvailableParameterDefinitions.Add(ParameterDefinitions);
}
return AvailableParameterDefinitions;
}
const TArray<UNiagaraParameterDefinitions*> UNiagaraParameterDefinitions::GetSubscribedParameterDefinitions() const
{
TArray<UNiagaraParameterDefinitions*> OutSubscribedParameterDefinitions;
for (const FParameterDefinitionsBindingNameSubscription& Subscription : ExternalParameterDefinitionsSubscriptions)
{
OutSubscribedParameterDefinitions.Add(Subscription.SubscribedParameterDefinitions);
}
return OutSubscribedParameterDefinitions;
}
void UNiagaraParameterDefinitions::NotifyParameterDefinitionsChanged()
{
OnParameterDefinitionsChangedDelegate.Broadcast();
}
#undef LOCTEXT_NAMESPACE