InstantiateDynamicSlice issue

0

Hi,

in Lumberyard 1.16 transform is not applying to root entity, when I try to instantiate dynamic slice:

	EBUS_EVENT_RESULT(ticket,
AzFramework::GameEntityContextRequestBus,
InstantiateDynamicSlice, asset,
AZ::Transform::CreateTranslation(AZ::Vector3(10.0f, 0.0f, 0.0f)),
nullptr/*customIdMapper*/);

Edit:

The reason for this is the mismatch of transform components.

Using the method described above, the created entity contains AzToolsFramework::Components::TransformComponent, but the checking happens with AzFramework::TransformComponent(GameEntityContextComponent.cpp line 455).

asked 5 years ago166 views
7 Answers
0
Accepted Answer

The problem was in the wrong asset extension:


// wrong
const char* assetPath = "Slices/Player.slice";
// correct (even though the file on the disk is named Player.slice)
const char* assetPath = "Slices/Player.dynamicslice";
AZ::Data::AssetId assetId;
EBUS_EVENT_RESULT(assetId,
AZ::Data::AssetCatalogRequestBus,
GetAssetIdByPath,
assetPath,
AZ::AzTypeInfo<AZ::DynamicSliceAsset>::Uuid()/*typeToRegister*/,
false/*autoRegisterIfNotFound*/);
AZ_Assert(assetId.IsValid(), "Asset is not found.");
AZ::Data::Asset<AZ::DynamicSliceAsset>asset;
asset.Create(assetId, true/*queueLoad*/);
AZ_Assert(asset.GetId().IsValid(), "Asset is not created.");
answered 5 years ago
0

I made global Spawner for my systemcomponent like so

  void LyTanksSystemComponent::SpawnSlice(const AZStd::string & sliceName, const AZ::Vector3 & pos)
{
AZ::Data::AssetId sliceAssetId;
EBUS_EVENT_RESULT(sliceAssetId, AZ::Data::AssetCatalogRequestBus, GetAssetIdByPath, sliceName.c_str(), 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(pos));
using namespace AzFramework;
static EntityContextId gameEntityContextId = EntityContextId::CreateNull();
if (gameEntityContextId.IsNull())
{
GameEntityContextRequestBus::BroadcastResult(gameEntityContextId, &GameEntityContextRequestBus::Events::GetGameEntityContextId);
}
SliceInstantiationTicket ticket;
ticket.m_contextId = gameEntityContextId;
GameEntityContextRequestBus::BroadcastResult(ticket, &GameEntityContextRequestBus::Events::InstantiateDynamicSlice, sliceAsset, transform, nullptr);
//LmbrCentral::SpawnerComponentRequestBus::EventResult(ticket, m_childEntity->GetId(), &LmbrCentral::SpawnerComponentRequestBus::Events::SpawnSliceAbsolute, sliceAsset, transform);
SliceInstantiationResultBus::MultiHandler::BusConnect(ticket);
}
}
}
answered 5 years ago
0

Hi @REDACTEDUSER

answered 5 years ago
0

Hey guys,

I appreciate your assistance!

So far Fluffy's function has same result as mine and SpawnerComponent::SpawnSliceAbsolute works fine.

By the way, I have noticed that in my case in OnSlicePreInstantiate for some reason the transform component appears not to be found.(GameEntityContextComponent.cpp line 455).

answered 5 years ago
0

I guess it spawns at 0,0,0.

Edit:

You can replicate the error if you setup SpawnerComponent from c++ side:


AZ::Entity* entity = aznew AZ::Entity("AnyName");
// from CustomComponent call SpawnerComponent::SpawnSliceAbsolute
entity->CreateComponent<CustomComponent>(); entity->CreateComponent(LmbrCentral::SpawnerComponentTypeId);
entity->Init();
entity->Activate();
AZ::Data::AssetId assetId;
EBUS_EVENT_RESULT(assetId,
AZ::Data::AssetCatalogRequestBus,
GetAssetIdByPath,
slicePath,
AZ::AzTypeInfo<AZ::DynamicSliceAsset>::Uuid()/*typeToRegister*/,
false/*autoRegisterIfNotFound*/);
AZ_Assert(assetId.IsValid(), "Slice is not found.");
AZ::Data::Asset<AZ::DynamicSliceAsset>asset;
asset.Create(assetId, true/*queueLoad*/);
AZ_Assert(asset.GetId().IsValid(), "Asset is not created.");
EBUS_EVENT_ID(entity->GetId(),
LmbrCentral::SpawnerComponentRequestBus,
SetDynamicSlice, asset);
answered 5 years ago
0

Transform is applying if i set it in OnSliceInstantiated:

  ...
// Set initial transform for slice root entity
for (AZ::Entity* entity : address.second->GetInstantiated()->m_entities)
{
AZ::EntityId parentId; EBUS_EVENT_ID_RESULT(parentId,entity->GetId(),AZ::TransformBus,GetParentId);
if (!parentId.IsValid())
{
EBUS_EVENT_ID(entity->GetId(),
AZ::TransformBus,
SetWorldTM,
sliceInfo.transform);
break;
}
}

but that is workaround and does not solve the issue which I described above.

answered 5 years ago
0

yeah, I faced with almost similar issue, here https://forums.awsgametech.com/t/on-what-ebus-event-the-transform-component-with-entitys-childrens-are-ready-for-grab-for-internal-logic/5995/1 (components are not ready for using)

You may try to use OnSliceInstantiated instead OnSlicePreInstantiate on the OnSliceInstantiated notification from SpawnerComponent.

I'm catching all instanced bullets(if you need only root of each spawned Slice use m_mataentities) and apply for each bullet some initial impulse like so

  void EnemyTankComponent::OnSliceInstantiated(const AZ::Data::AssetId & assetId, const AZ::SliceComponent::SliceInstanceAddress & address)
{
for (AZ::Entity* spawnedEntity : address.second->GetInstantiated()->m_entities)
{
if (spawnedEntity)
{
AzFramework::PhysicsComponentRequestBus::Event(spawnedEntity->GetId(), &AzFramework::PhysicsComponentRequestBus::Events::SetMass, m_bullet_mass);
AZ::Vector3 forward = m_modules[TankModule::SPAWN]->GetTransform()->GetWorldTM().GetBasisY();
////AZ::Transform tm = m_entity->GetTransform()->GetWorldTM().GetInverseFast();
////AZ::Vector3 forward = AZ::Vector3(0.0f, 1.0f, 0.0f) * tm;
AzFramework::PhysicsComponentRequestBus::Event(spawnedEntity->GetId(), &AzFramework::PhysicsComponentRequestBus::Events::AddImpulse, forward * m_bullet_impulse);
}
}
}
<br>
answered 5 years ago

This post is closed: Adding new answers, comments, and votes is disabled.