Cannot get mutable Shared Fragment (Mass)

I am having issues with initializing a subsystem and then creating a sharedsubsystemfragment in my cpp code.

Here is my setup now:

void UUpdateFollowStateProcessor::ConfigureQueries()
{
	EntityQuery.AddRequirement<FTransformFragment>(EMassFragmentAccess::ReadOnly);
	EntityQuery.AddRequirement<FFollowPlayerFragment>(EMassFragmentAccess::ReadWrite);
	EntityQuery.AddRequirement<FInitialSpawnLocationFragment>(EMassFragmentAccess::ReadOnly);
	EntityQuery.AddConstSharedRequirement<FFollowBehaviorParameters>(EMassFragmentPresence::All);
	EntityQuery.AddSharedRequirement<FPlayerStatusSubsystemSharedFragment>(EMassFragmentAccess::ReadWrite);
	// in here and in FollowPlayerProcessor we might consider using simple Subsystem and not a fragmented subsystem.
	EntityQuery.RegisterWithProcessor(*this);
}

void UUpdateFollowStateProcessor::Execute(FMassEntityManager& EntityManager, FMassExecutionContext& Context)
{
	FPlayerStatusSubsystemSharedFragment& PlayerStatusSubsystemSharedFragment = Context.GetMutableSharedFragment<FPlayerStatusSubsystemSharedFragment>();

And in my trait that I add to my entities that are spawned via the Mass Spawner, I do:

UCLASS(meta = (DisplayName = "Follow Behavior"))
class NEWCORERUNTIME_API UFollowBehaviorTrait : public UMassEntityTraitBase
{
	GENERATED_BODY()

public:

	virtual void BuildTemplate(FMassEntityTemplateBuildContext& BuildContext, const UWorld& World) const override;

	UPROPERTY(EditAnywhere, Category="Follow")
	FFollowBehaviorParameters FollowParameters;
};

void UFollowBehaviorTrait::BuildTemplate(FMassEntityTemplateBuildContext& BuildContext, const UWorld& World) const
{
	FMassEntityManager& EntityManager = UE::Mass::Utils::GetEntityManagerChecked(World);

	const FFollowBehaviorParameters FollowValidated = FollowParameters.GetValidated();
	const FConstSharedStruct FollowSharedFragment = EntityManager.GetOrCreateConstSharedFragment(FollowValidated);
	BuildContext.AddConstSharedFragment(FollowSharedFragment);

	UMassPlayerStatusSubsystem* PlayerStatusSubsystem = World.GetSubsystem<UMassPlayerStatusSubsystem>();
	check(PlayerStatusSubsystem);

	FPlayerStatusSubsystemSharedFragment PlayerStatusSubsystemSharedFragment;
	PlayerStatusSubsystemSharedFragment.PlayerStatusSubsystem = PlayerStatusSubsystem;
	uint32 SubsystemHash = UE::StructUtils::GetStructCrc32(FConstStructView::Make(PlayerStatusSubsystemSharedFragment));
	FSharedStruct SubsystemFragment = EntityManager.GetOrCreateSharedFragmentByHash<FPlayerStatusSubsystemSharedFragment>(SubsystemHash, PlayerStatusSubsystemSharedFragment);
	BuildContext.AddSharedFragment(SubsystemFragment);
}

but when I PIE, I get an exception that says:

Shared Fragment requirement not found: PlayerStatusSubsystemSharedFragment.

I also, tried to remove the GetMutableSharedFragment from the processor code and checked the Mass Debugger, an I saw that the entities have that SharedFragment on them, so I don’t understand what is the issue here.

Thank you all!


This is the screenshot from the Mass Debugger.

Solution found! The context was wrong.
What I needed to do is pass the correct context:

	EntityQuery.ForEachEntityChunk(EntityManager, Context, [this](FMassExecutionContext& Context)
	{
		FPlayerStatusSubsystemSharedFragment& PlayerStatusSubsystemSharedFragment = Context.GetMutableSharedFragment<FPlayerStatusSubsystemSharedFragment>();
		UMassPlayerStatusSubsystem* PlayerStatusSubsystem = PlayerStatusSubsystemSharedFragment.PlayerStatusSubsystem.Get();

I had to move the getter into the Context per Chunk.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.