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).

已提问 6 年前170 查看次数
7 回答
0
已接受的回答

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.");
已回答 5 年前
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);
}
}
}
已回答 6 年前
0

Hi @REDACTEDUSER

已回答 6 年前
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).

已回答 6 年前
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);
已回答 6 年前
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.

已回答 6 年前
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>
已回答 6 年前

该帖子已关闭:已禁用添加新回答、评论和投票。