Duplicating a pawn that use GameplayAblilities plugin's AttributeSet does not work

UE-81109 describes the issue.

Is it common to have issues when duplicating a blueprint in the editor using CNTL-W? My BP actor is a child of my custom C++ that has an attributeset that gets created in the C++ constructor using CreateDefaultSubobject. The original works fine. The duplicate has the attribute set = NULL. I created a new BP based on the same C++ and it works just fine.

1 Like

UE-81109 describes the issue.

Just bumped into this bug. The AttributeSet is set properly and working in the Constructor on the Duplicated Blueprint. But somewhere between the Contructor and BeginPlay, the AttributSet is set to null.

One “workaround” is to reparent the glitched blueprint and then reparent back. But that will of course lose you any properties exclusive to the original parent. But it will at least fix the bug and stop crashing the editor.

So one thing you could do, would be to make a new (temporary?) c++ Class that inherits from your custom Character, but doesn’t change anything. So every time to you need to duplicate the blueprint of a Character, you CTRL+W then later reparent to the temporary C++ Class, then reparent back.

Is it common to have issues when duplicating a blueprint in the editor using CNTL-W?

Unfortunately that is way too common. It is really bizarre that duplicating doesn’t actually… duplicates. There are 4 different parts of my code breaking when I duplicate a Blueprint, after an entire day I finally found issue UE-81109 was the root behind my Health not updating on the duplicated Blueprint. Now I’ll move on to figure why the Blackboard, Anim Notify and Hitbox overlap also stop working properly on the duplicate…

Since I just had to deal with this, here is a workaround.

Create your attribute sets in PreInitializeComponents() instead of the constructor.

Example:
void ASomeActor::PreInitializeComponents()
{
Super::PreInitializeComponents();
CoreAttributes = NewObject(this, TEXT(“CoreAttributes”));
}

As long as you store the set as a Uproperty pointer on the class it will be picked up by the GAS component and also GCed.

Older engine versions also had the issue of null garbage being left in the component, but 4.25 added a check for that in UAbilitySystemComponent::InitializeComponent().

1 Like

Interesting. I use the below. I don’t know if that was the case 2 years ago or not. Due to this bug, I never duplicate this way.

	// Create the attribute set, this replicates by default
	// Adding it as a sub object of the owning actor of an AbilitySystemComponent
	// automatically registers the AttributeSet with the AbilitySystemComponent
	HardRefAWAttributeCore = ObjectInitializer.CreateDefaultSubobject<UAWAttributeCore>(this, TEXT("AWAttributeCore"));

Throwing a little update on here. I found that a lot of floated solutions were working for us with replication–havent tested this with a packaged build yet, but setting things up like this seems to make things work with replication.

void AEnemyCharacterBase::PreInitializeComponents()
{
	Super::PreInitializeComponents();
	HardRefAttributeSetBase = NewObject<UUnitAttributeSet>(this, TEXT("EnemyAttributeSetBase"), RF_Transient);
	HardRefAttributeSetBase->SetNetAddressable();
}

Thank you man! Just saved my day!