Native class
UGBAEditorSubsystem#
Editor subsystem to handle Gameplay Attribute property renames in Blueprint.
Changing a variable name needs to be handled to prevent crash from happening if any Gameplay Effects is using it, and if that Gameplay Effect was previously opened and focused again in editor (not relevant anymore since rework into using TWeakFieldPtr<FProperty>).
The Details customization for the Attribute or Effect using those needs to be updated "live", whereas in the usual case of having Attributes defined in cpp, code needs to be recompiled and editor restarted.
With Blueprints, we need a way to rename attributes and have Gameplay Effects (or other K2 nodes using Gameplay Attribute) updated to reference the new property.
Subsystem register to an OnVariableRename delegate fired off from UGBAAttributeSetBlueprint
, and handle any editor specific code.
When a rename happens, this event fires off and triggers the following logic in this subsystem:
- Get all referencers to the original Attribute Set Blueprints (its package name) 2. Check if any referencers is currently opened in Editor, store them (TODO: Check if renamed attribute is actually used, a referencer can be referencing other attributes from same BP, in which case closing asset editor is not required) 3. Close any opened referencers in Editor 4. Update CDO for any referencers to update property from Old Attribute property to the new one 5. Reopen any closed editor previously, if any
Internal structs#
-
public
Data holder for Blueprints / K2 Nodes pin that needs an update
Methods#
-
publicstatic voidCloseEditors(const TArray<FAssetData>& InAssets,
TArray<FAssetData>& OutClosedAssetsChecks if given asset is currently being edited, and if so, closes the editor (required prior to file deletion)
-
virtual voidDeinitialize()
-
TSharedPtr<IGBAAttributeReferencerHandler>FindAssetDependencyHandler(const FName& InReferencer,
TWeakObjectPtr<UObject>& OutDefaultObjectReturns the associated referencer handler (if any) registered for the class default object of InReferencer.AssetId
-
static UGBAEditorSubsystem&Get()
Static convenience method to return storm sync notification subsystem
-
static UGameplayEffect*GetGameplayEffectCDO(const FAssetDependency& InAssetDependency
Tries to load UObject, checks if it is a gameplay effect and returns the CDO for that effect
-
static UGameplayEffect*GetGameplayEffectCDO(const FString& InPackageName
Tries to load UObject, checks if it is a gameplay effect and returns the CDO for that effect
-
static voidGetGameplayEffectReferencers(const FName& InPackageName,
TArray<FAssetDependency>& OutReferencers,
TArray<FAssetData>& OutAssetsDataHelper method to return all Gameplay Effect referencers for a given package name
-
static FStringGetLoadClassPackagePath(const FString& InPackageName
From a package name (eg. /Game/Foo/Bar) returns the load path suitable to use with StaticLoadClass for a Blueprint load (eg. eg. /Game/Foo/Bar.Bar_C)
-
TArray<FPinToModify>GetPinsToModify(const FString& InPackageName,
const FString& InOldPropertyName,
const FString& InNewPropertyNameGather the list of Blueprints with K2Node using a Pin Attribute parameter
-
static voidGetReferencers(const FName& InPackageName,
TArray<FAssetDependency>& OutReferencers,
TArray<FAssetData>& OutAssetsDataHelper method to return all referencers for a given package name
-
static voidGetReferencers(const FName& InPackageName,
TArray<FAssetDependency>& OutReferencers,
TArray<FAssetData>& OutAssetsData,
const TArray<UClass*>& InAllowedClassesHelper method to return all referencers for a given package name
-
static TArray<FAssetDependency>GetReferencersOfClass(const TArray<FAssetDependency>& InReferencers,
const UClass* InFilterClassFilters the passed in FAssetDependency referencers returning only the one that are child class of filter class
-
voidHandleAttributeRename(const FName& InPackageName,
const FName& InOldPropertyName,
const FName& InNewPropertyNameHandler for OnVariableRenamed delegate.
-
static voidHandleMessageLogLinkActivated(const TSharedRef<IMessageToken>& InToken
Bring focus and navigate to the token object
-
static voidHandleNextTick(FName InPackageName,
const TArray<FString> InClosedAssetsLittle timer delegate to delay re-opening of assets to the next frame (unused right now. TODO: check if still needed)
-
voidHandlePins(const TArray<FPinToModify>& InPinsToModify,
const UBlueprint* InOwnerAttributeSetBP,
const FName& InNewPropertyNameGoes through the list of pins to modify, actually update the pin to point to the new attribute property name
-
voidHandlePostCompile(const FName& InPackageName
TODO: Probably not needed anymore since refactoring of Slate widget to use TWeakFieldPtr (that method was used to close any active / opened GE Blueprint to avoid a crash) Addendum: Still needed, if we have a ref to one of the attributes of a BP that is compiled, may crash (seen it consistently with Gameplay Cues Magnitude Attribute) Better TODO: See if we can "pause" the details customization (instead of closing / re-opening), or "refresh"
-
voidHandlePreCompile(const FName& InPackageName
Triggered by FGBABlueprintEditor just before FBlueprintEditor::Compile()
-
virtual voidInitialize(FSubsystemCollectionBase& Collection
-
static boolIsAssetCurrentlyBeingEdited(const TSharedPtr<IToolkit>& InAssetEditor,
const UObject* InAssetChecks if given UObject asset is currently being edited by an Asset Editor (is it opened in editor right now?)
-
static voidOpenClosedEditors(const TArray<FString>& InClosedAssets
Takes a list of package names to ask the Asset Editor subsystem to open
-
static boolParseAttributeFromDefaultValue(const FString& InDefaultValue,
FString& OutPackageName,
FString& OutAttributeNameExtracts attribute owner info from Pin Default value and returns it as a PackageName equivalent
-
virtual voidRegisterReferencerHandler(const FName& InClassName,
const TSharedPtr<IGBAAttributeReferencerHandler>& InHandlerAdds a custom referencer handler for given InClassName (without the class prefix, eg. GameplayEffect instead of UGameplayEffect)
-
virtual voidUnregisterReferencerHandler(const FName& InClassName
Removes a previously registered handler
-
voidUpdateK2NodeReferencers(const FName& InPackageName,
const FName& InOldPropertyName,
const FName& InNewPropertyNameHandles update of all UK2Node_CallFunction nodes with Attribute Pin parameter to point to the new FGameplayAttribute that was renamed
-
voidUpdateReferencers(TArray<FAssetData> InReferencers,
const FName& InPackageName,
const FName& InOldPropertyName,
const FName& InNewPropertyNameHandles update of FGameplayAttribute properties in the referencers asset to point to the new FGameplayAttribute that was renamed
Fields#
-
publicbool bIsHandlingRename = false
Keeps track of whether we are currently handling a rename (and prevent rename code path to run again when we manually compile the BP at the end of this run)
-
static constexpr const TCHAR* LogName = TEXT("BlueprintAttributesLog")
The message log category
-
TArray<TSharedRef<FTokenizedMessage>> PendingMessages
List of pending tokenized messages representing an attribute ref updated
-
TMap<FName, TSharedPtr<IGBAAttributeReferencerHandler>> RegisteredHandlers
List of referencer handler registered via RegisterReferencerHandler()