Can you guys tell me how to Spawn dynamic Slices from C++?

I have my own SystemComponent and I want to teach it to spawning something, how to do it?

Earlier I saw Spawner Component, can we use it with system? Or maybe we can do Spawning without any other component and directly ?

You can spawn slices fairly simply through C++ by doing the following:


#include <AzCore/Asset/AssetManagerBus.h>
#include <AzFramework/Entity/GameEntityContextBus.h>
// Firstly, find the slice asset ID using the file name of the slice
AZ::Data::AssetId sliceAssetID;
EBUS_EVENT_RESULT(sliceAssetID, AZ::Data::AssetCatalogRequestBus, GetAssetIdByPath, "Slices/TestSlice.dynamicslice", AZ::AzTypeInfo<AZ::DynamicPrefabAsset>::Uuid(), true);
if (sliceAssetID.IsValid())
{
// Using the valid ID, find the actual slice asset
AZ::Data::Asset<AZ::DynamicSliceAsset> sliceAsset;
sliceAsset.Create(sliceAssetID, true);
if (sliceAsset.GetId().IsValid())
{
// Actually spawn the slice
AZ::Transform transform(AZ::Transform::CreateTranslation(AZ::Vector3(0, 0, 0)));
AzFramework::SliceInstantiationTicket ticket;
EBUS_EVENT_RESULT(ticket, AzFramework::GameEntityContextRequestBus, InstantiateDynamicSlice, sliceAsset, transform, nullptr);
}
}

If you’re looking to get a little more complex, you can create your own version of a spawner. Have a look at ‘LmbrCentral\Code\Source\Scripting\SpawnerComponent.h’, especially the ‘SliceInstantiationResultBus::MultiHandler’ functions and the ‘SpawnSliceInternalRelative’ function.

Inherit your spawner class from AzFramework::SliceInstantiationResultBus::MultiHandler and make sure to implement:

void OnSlicePreInstantiate(const AZ::Data::AssetId& sliceAssetId, const AZ::SliceComponent::SliceInstanceAddress& sliceAddress) override;
void OnSliceInstantiated(const AZ::Data::AssetId& sliceAssetId, const AZ::SliceComponent::SliceInstanceAddress& sliceAddress) override;
void OnSliceInstantiationFailed(const AZ::Data::AssetId& sliceAssetId) override;

Hopefully that helps.

Thx! your code works!

gyazo gif

But before I readed your reply(and see your code) I was working on another menthod I was trying to create SpawnerComponent for mySystemComponent (I guess it’s wrong decision, because system components and regular components various)


#include <LmbrCentral/Scripting/SpawnerComponentBus.h>
void MyCustomSystemComponent::Activate()
{
m_entity->CreateComponent(LmbrCentral::SpawnerComponentTypeId);
//m_entity->Init();
//m_entity->Activate();
MyCustomSystemRequestBus::Handler::BusConnect();
}

and I was in seeking code snippet how to convers path to slice(string) into type

AZ::Data::AssetId sliceAssetId

I wanted to doing Spawning of Slice with internal SpawnerComponent with helps sending to it event like this:

LmbrCentral::SpawnerComponentRequestBus::Event(GetEntityId(), &LmbrCentral::SpawnerComponentRequestBus::Events::SpawnSliceAbsolute, sliceAsset, transform);

code

Anyways your code works now, thank you!

Yep, my method works too!) But I do not create SpawnerComponent for systemEntity with are using for SystemComponents like my system. I just create dynamic entity within my system and create for this entity - SpawnerComponent.

	void MyCustomSystemComponent::Activate()
{
//AZ::Entity* newEntity = aznew AZ::Entity("testEntity");
newEntity = aznew AZ::Entity("testEntity");
newEntity->CreateComponent(LmbrCentral::SpawnerComponentTypeId);
newEntity->Init();
newEntity->Activate();
AZ::Vector3 pos(512.0f, 512.0f, 50.0f); // position
AZ::TransformBus::Event(newEntity->GetId(), &AZ::TransformInterface::SetWorldTM, AZ::Transform::CreateTranslation(pos));
MyCustomSystemRequestBus::Handler::BusConnect();
}

so now this event works too,

	void MyCustomSystemComponent::AddSpawnSliceRequest(const AZStd::string & sliceName, const AZ::Vector3 & pos)
{
AZ::SimpleLcgRandom m_randomGenerator;
//m_randIndex = m_randomGenerator.GetRandom();
m_spawnPos = AZ::Vector3(
1024.0f * 0.5f + m_randomGenerator.GetRandomFloat() * (16.0f),
1024.0f * 0.5f + m_randomGenerator.GetRandomFloat() * (16.0f),
45.f
);
AZ::Data::AssetId sliceAssetId;
EBUS_EVENT_RESULT(sliceAssetId, AZ::Data::AssetCatalogRequestBus, GetAssetIdByPath, "Slices/DynamicSlice.dynamicslice", AZ::AzTypeInfo<AZ::DynamicPrefabAsset>::Uuid(), true);
if (sliceAssetId.IsValid())
{
// Using the valid ID, find the actual slice asset
AZ::Data::Asset<AZ::DynamicSliceAsset> sliceAsset;
sliceAsset.Create(sliceAssetId, true);
if (sliceAsset.GetId().IsValid())
{
AZ::Transform transform(AZ::Transform::CreateTranslation(m_spawnPos));
AzFramework::SliceInstantiationTicket ticket;
EBUS_EVENT_RESULT(ticket, AzFramework::GameEntityContextRequestBus, InstantiateDynamicSlice, sliceAsset, transform, nullptr);
if (ticket) {
//AzFramework::SliceInstantiationResultBus::MultiHandler::BusConnect(ticket);
}
if (newEntity)
{
LmbrCentral::SpawnerComponentRequestBus::Event(newEntity->GetId(), &LmbrCentral::SpawnerComponentRequestBus::Events::SpawnSliceAbsolute, sliceAsset, transform);
}
}
}
}