Mass Representation -> Actor Spawning

how to initialize the existing mass representation processor to spawn requested actors ?…



void UControlProcessor::Execute(FMassEntityManager& EntityManager, FMassExecutionContext& Context){// Einfacher Zugriff - sucht nach ANY Subsystem, das das Interface implementiertUWorld* World = GetWorld();USceneBase* SceneBase = ULUtility::GetWorldSubsystem(World);if (SceneBase == nullptr)return;


uint32 CurrentSystemID = SceneBase->GetSystemId();
if (CurrentSystemID == 0)
    return;

LastSystemID = CurrentSystemID;
EntityQuery.ForEachEntityChunk(Context, [SceneBase, CurrentSystemID](FMassExecutionContext& Context)
{
    const int32 NumEntities = Context.GetNumEntities();
    const TArrayView<FMassRepresentationLODFragment> PresentationLODFrags = Context.GetMutableFragmentView<FMassRepresentationLODFragment>();
    const TArrayView<FMassRepresentationFragment> PresentationFrags = Context.GetMutableFragmentView<FMassRepresentationFragment>();
    const TArrayView<const FSimulationFragment> SimulationFrags = Context.GetFragmentView<FSimulationFragment>();
    const TArrayView<const FTransformFragment> TransformFrags = Context.GetFragmentView<FTransformFragment>();

    for (int32 i = 0; i < NumEntities; ++i)
    {
        FMassRepresentationLODFragment& LodFragmen = PresentationLODFrags[i];
        FMassRepresentationFragment&    VisualFrag = PresentationFrags[i];

        const FSimulationFragment&      Simulation = SimulationFrags[i];
        const FTransformFragment&       Transform  = TransformFrags[i];
        const FMassEntityHandle&        Entity = Context.GetEntity(i);

        if (Simulation.SystemID == CurrentSystemID && LodFragmen.LOD != EMassLOD::High)
        {
            LodFragmen.LOD = EMassLOD::High;
            LodFragmen.Visibility = EMassVisibility::CanBeSeen;
            LodFragmen.LODSignificance = 0;

            VisualFrag.HighResTemplateActorIndex = SceneBase->RetrieveActorIndex(Entity, Simulation.ID, Simulation.TypeID);
            VisualFrag.LowResTemplateActorIndex = SceneBase->RetrieveActorIndex(Entity, Simulation.ID, Simulation.TypeID);
            VisualFrag.PrevTransform = Transform.GetTransform();
        }
        
        if (Simulation.SystemID != CurrentSystemID && LodFragmen.LOD == EMassLOD::High)
        {
            LodFragmen.LOD = EMassLOD::Off;
            VisualFrag.HighResTemplateActorIndex =  -1;
            VisualFrag.LowResTemplateActorIndex = -1;
            VisualFrag.PrevTransform = Transform.GetTransform();
        }

        int32 xxx = 0;
    }
});
}


how to enable the build in UMassRepresentationProcessor, properly
which fragments do i have to register on my archtype?
a minimalistic, working example would be great

Create your archetype via data asset. Then have this looked up on your processor that you want to spawn.

The data asset should be where your fragments live. One of the data assets here should work fine: LEGACY - Your First 60 Minutes with Mass | Tutorial

Then in your code, get the entity manager, get a command buffer, you’ll have to post the request to spawn. I would NOT advise building all the template items in code, use the data asset pipeline.

///
/// Spawns one Mass entity at this actor’s transform, respecting the
/// configured maximum spawn count and using the configured Mass entity
/// configuration asset.
///
void AMassSpawner_OneOffsWithCap::SpawnAtSelf()
{
// Respect maximum spawn count if configured.
if (m_nMaxSpawnCount > 0 && m_nCurrentCounter >= m_nMaxSpawnCount)
{
return;
}

UWorld* pWorld = GetWorld();
if (pWorld == nullptr || m_poEntityConfig == nullptr)
{
	UE_LOG(LogTemp, VeryVerbose,
		TEXT("MyMassSpawner: World or EntityConfig missing on %s"),
		*GetName());
	return;
}

UMassEntitySubsystem* pEntitySubsystem = pWorld->GetSubsystem<UMassEntitySubsystem>();
if (pEntitySubsystem == nullptr)
{
	return;
}

const FMassEntityTemplate& oTemplate =
	m_poEntityConfig->GetOrCreateEntityTemplate(*pWorld);

if (!oTemplate.IsValid())
{
	UE_LOG(LogTemp, Error, TEXT("MyMassSpawner: Entity template invalid"));
	return;
}

// Ensure a spawn location processor is available/initialized.
EnsureLocationProcessor();
if (m_oLocationProcessor == nullptr)
{
	UE_LOG(LogTemp, Error,
		TEXT("MyMassSpawner: Failed to create UMassSpawnLocationProcessor"));
	return;
}

const int32 nNumToSpawn = 1;
const FTransform oSpawnTransform = GetActorTransform();
const FMassEntityTemplateID oTemplateId = oTemplate.GetTemplateID();

m_nCurrentCounter += nNumToSpawn;

FMassEntityManager& oEntityManager = pEntitySubsystem->GetMutableEntityManager();
FMassCommandBuffer& oCmdBuffer = oEntityManager.Defer();

using FCreateCmd = FMassDeferredCommand<EMassCommandOperationType::Create>;

oCmdBuffer.PushCommand<FCreateCmd>(
	[this, pWorld, oTemplateId, oSpawnTransform, nNumToSpawn]
	(FMassEntityManager& oInEntityManager)
	{
		UMassSpawnerSubsystem* pSpawnerSystem =
			UWorld::GetSubsystem<UMassSpawnerSubsystem>(pWorld);
		if (pSpawnerSystem == nullptr)
		{
			return;
		}

		FInstancedStruct oTransformStruct;
		oTransformStruct.InitializeAs<FMassTransformsSpawnData>();

		FMassTransformsSpawnData& oTransformData =
			oTransformStruct.GetMutable<FMassTransformsSpawnData>();

		oTransformData.Transforms.Init(oSpawnTransform, nNumToSpawn);

		const FConstStructView oSpawnDataView(oTransformStruct);

		TArray<FMassEntityHandle> aNewEntities;
		pSpawnerSystem->SpawnEntities(
			oTemplateId,
			static_cast<uint32>(nNumToSpawn),
			oSpawnDataView,
			UMassSpawnLocationProcessor::StaticClass(),
			aNewEntities);

		m_aSpawnedEntities.Append(aNewEntities);
	});

}

yea its a bit more complicated…
i have x solarsystems with y celestial bodies.
i want to simulate all populated systems.
but only render the current system i visite.
so i have to tell mass im in this system atm spawn or despawn actors.

i would also prefere not using a massentityconfig for some reason, but can live with it.

what i dont get is how to use the UMassVisualisationProcessor “PipeLine” eveen deep seek with
search function tells me its not good documented at all :smiley:

Yes, so what i pasted runs on an Actor, if you have a bounding <w/e> or a way to know when an actor should be activated; i call that from an Actor. You can call that at anytime when running / in a world; it injects into mass the spawned entities you requested from a template.

This is a very basic ‘xp pickup’ entity config i have. You could create these same in code if you wanted to not go the entity config route.

Magnet effect and pickup physics and radial pickup are my own, but that’s the basics of what you should run to ‘see something in the world’