Addressed PR feedback
This commit is contained in:
+4
-4
@@ -10,16 +10,16 @@
|
||||
Version="0"
|
||||
GeneratePropertyFriend="True"
|
||||
Namespace="ScriptCanvas"
|
||||
Description="Spawn">
|
||||
Description="Spawns a selected prefab, positioned using the provided transform inputs">
|
||||
|
||||
<Input Name="Request Spawn" OutputName="Spawn Requested">
|
||||
<Parameter Name="Translation" Type="Data::Vector3Type" Description="Position to spawn"/>
|
||||
<Parameter Name="Rotation " Type="Data::Vector3Type" Description="Rotation of spawn (in degrees)"/>
|
||||
<Parameter Name="Scale " Type="Data::NumberType" DefaultValue="1" Description="Scale of spawn"/>
|
||||
<Parameter Name="Rotation" Type="Data::Vector3Type" Description="Rotation of spawn (in degrees)"/>
|
||||
<Parameter Name="Scale" Type="Data::NumberType" DefaultValue="1" Description="Scale of spawn"/>
|
||||
</Input>
|
||||
|
||||
<Output Name="On Spawn">
|
||||
<Parameter Name="SpawnedEntitiesList" Type="AZStd::vector<Data::EntityIDType>" Description="List of spawned entities sorted by hiearchy with the root being first"/>
|
||||
<Parameter Name="SpawnedEntitiesList" Type="AZStd::vector<Data::EntityIDType>" Description="List of spawned entities sorted by hierarchy with the root being first"/>
|
||||
</Output>/>
|
||||
|
||||
<Property Name ="m_spawnableAsset" Type="AZ::Data::Asset<AzFramework::Spawnable>" Serialize="true">
|
||||
|
||||
+109
-111
@@ -15,127 +15,125 @@
|
||||
#include <AzFramework/Components/TransformComponent.h>
|
||||
#include <AzFramework/Spawnable/SpawnableAssetHandler.h>
|
||||
|
||||
namespace ScriptCanvas
|
||||
namespace ScriptCanvas::Nodeables::Spawning
|
||||
{
|
||||
namespace Nodeables
|
||||
SpawnNodeable::SpawnNodeable(const SpawnNodeable& rhs)
|
||||
: m_spawnableAsset(rhs.m_spawnableAsset)
|
||||
{}
|
||||
|
||||
SpawnNodeable& SpawnNodeable::operator=(SpawnNodeable& rhs)
|
||||
{
|
||||
namespace Spawning
|
||||
m_spawnableAsset = rhs.m_spawnableAsset;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SpawnNodeable::OnInitializeExecutionState()
|
||||
{
|
||||
if (!AZ::TickBus::Handler::BusIsConnected())
|
||||
{
|
||||
SpawnNodeable::SpawnNodeable(const SpawnNodeable& rhs)
|
||||
AZ::TickBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
m_spawnTicket = AzFramework::EntitySpawnTicket(m_spawnableAsset);
|
||||
}
|
||||
|
||||
void SpawnNodeable::OnDeactivate()
|
||||
{
|
||||
AZ::TickBus::Handler::BusDisconnect();
|
||||
|
||||
m_spawnTicket = AzFramework::EntitySpawnTicket();
|
||||
}
|
||||
|
||||
void SpawnNodeable::OnTick([[maybe_unused]] float delta, [[maybe_unused]] AZ::ScriptTimePoint timePoint)
|
||||
{
|
||||
AZStd::vector<Data::EntityIDType> swappedSpawnedEntityList;
|
||||
AZStd::vector<size_t> swappedSpawnBatchSizes;
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_idBatchMutex);
|
||||
|
||||
swappedSpawnedEntityList.swap(m_spawnedEntityList);
|
||||
swappedSpawnBatchSizes.swap(m_spawnBatchSizes);
|
||||
}
|
||||
|
||||
AZ::EntityId* batchBegin = swappedSpawnedEntityList.data();
|
||||
for (size_t batchSize : swappedSpawnBatchSizes)
|
||||
{
|
||||
if (batchSize == 0)
|
||||
{
|
||||
m_spawnableAsset = rhs.m_spawnableAsset;
|
||||
continue;
|
||||
}
|
||||
|
||||
void SpawnNodeable::OnInitializeExecutionState()
|
||||
{
|
||||
if (!AZ::TickBus::Handler::BusIsConnected())
|
||||
{
|
||||
AZ::TickBus::Handler::BusConnect();
|
||||
}
|
||||
AZStd::vector<AZ::EntityId> spawnedEntitiesBatch(
|
||||
batchBegin, batchBegin + batchSize);
|
||||
|
||||
m_spawnTicket = AzFramework::EntitySpawnTicket(m_spawnableAsset);
|
||||
CallOnSpawn(AZStd::move(spawnedEntitiesBatch));
|
||||
|
||||
batchBegin += batchSize;
|
||||
}
|
||||
}
|
||||
|
||||
void SpawnNodeable::OnSpawnAssetChanged()
|
||||
{
|
||||
if (m_spawnableAsset.GetId().IsValid())
|
||||
{
|
||||
AZStd::string rootSpawnableFile;
|
||||
AzFramework::StringFunc::Path::GetFileName(m_spawnableAsset.GetHint().c_str(), rootSpawnableFile);
|
||||
|
||||
rootSpawnableFile += AzFramework::Spawnable::DotFileExtension;
|
||||
|
||||
AZ::u32 rootSubId = AzFramework::SpawnableAssetHandler::BuildSubId(AZStd::move(rootSpawnableFile));
|
||||
|
||||
if (m_spawnableAsset.GetId().m_subId != rootSubId)
|
||||
{
|
||||
AZ::Data::AssetId rootAssetId = m_spawnableAsset.GetId();
|
||||
rootAssetId.m_subId = rootSubId;
|
||||
|
||||
m_spawnableAsset = AZ::Data::AssetManager::Instance().
|
||||
FindOrCreateAsset<AzFramework::Spawnable>(rootAssetId, AZ::Data::AssetLoadBehavior::PreLoad);
|
||||
}
|
||||
|
||||
void SpawnNodeable::OnDeactivate()
|
||||
else
|
||||
{
|
||||
if (AZ::TickBus::Handler::BusIsConnected())
|
||||
{
|
||||
AZ::TickBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
m_spawnTicket = AzFramework::EntitySpawnTicket();
|
||||
}
|
||||
|
||||
void SpawnNodeable::OnTick([[maybe_unused]] float delta, [[maybe_unused]] AZ::ScriptTimePoint timePoint)
|
||||
{
|
||||
AZStd::vector<Data::EntityIDType> swappedSpawnedEntityList;
|
||||
AZStd::vector<size_t> swappedSpawnBatchSizes;
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_idBatchMutex);
|
||||
|
||||
swappedSpawnedEntityList.swap(m_spawnedEntityList);
|
||||
swappedSpawnBatchSizes.swap(m_spawnBatchSizes);
|
||||
}
|
||||
|
||||
AZ::EntityId* batchBegin = swappedSpawnedEntityList.data();
|
||||
for (size_t batchSize : swappedSpawnBatchSizes)
|
||||
{
|
||||
if (batchSize == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
AZStd::vector<AZ::EntityId> spawnedEntitiesBatch(
|
||||
batchBegin, batchBegin + batchSize);
|
||||
|
||||
CallOnSpawn(AZStd::move(spawnedEntitiesBatch));
|
||||
|
||||
batchBegin += batchSize;
|
||||
}
|
||||
}
|
||||
|
||||
void SpawnNodeable::OnSpawnAssetChanged()
|
||||
{
|
||||
if (m_spawnableAsset.GetId().IsValid())
|
||||
{
|
||||
AZStd::string rootSpawnableFile;
|
||||
AzFramework::StringFunc::Path::GetFileName(m_spawnableAsset.GetHint().c_str(), rootSpawnableFile);
|
||||
|
||||
rootSpawnableFile += AzFramework::Spawnable::DotFileExtension;
|
||||
|
||||
AZ::u32 rootSubId = AzFramework::SpawnableAssetHandler::BuildSubId(AZStd::move(rootSpawnableFile));
|
||||
|
||||
if (m_spawnableAsset.GetId().m_subId != rootSubId)
|
||||
{
|
||||
AZ::Data::AssetId rootAssetId = m_spawnableAsset.GetId();
|
||||
rootAssetId.m_subId = rootSubId;
|
||||
|
||||
m_spawnableAsset = AZ::Data::AssetManager::Instance().
|
||||
FindOrCreateAsset<AzFramework::Spawnable>(rootAssetId, AZ::Data::AssetLoadBehavior::Default);
|
||||
}
|
||||
|
||||
m_spawnableAsset.SetAutoLoadBehavior(AZ::Data::AssetLoadBehavior::PreLoad);
|
||||
}
|
||||
}
|
||||
|
||||
void SpawnNodeable::RequestSpawn(Data::Vector3Type translation, Data::Vector3Type rotation, Data::NumberType scale)
|
||||
{
|
||||
if (!m_spawnableAsset.IsReady())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto preSpawnCB = [this, translation, rotation, scale]([[maybe_unused]] AzFramework::EntitySpawnTicket& ticket,
|
||||
AzFramework::SpawnableEntityContainerView view)
|
||||
{
|
||||
AZ::Entity* rootEntity = *view.begin();
|
||||
|
||||
AzFramework::TransformComponent* entityTransform =
|
||||
rootEntity->FindComponent<AzFramework::TransformComponent>();
|
||||
|
||||
if (entityTransform)
|
||||
{
|
||||
AZ::Vector3 rotationCopy = rotation;
|
||||
AZ::Quaternion rotationQuat = AZ::Quaternion::CreateFromEulerAnglesDegrees(rotationCopy);
|
||||
|
||||
entityTransform->SetWorldTM(AZ::Transform(translation, rotationQuat, AZ::Vector3(scale, scale, scale)));
|
||||
}
|
||||
};
|
||||
|
||||
auto spawnCompleteCB = [this]([[maybe_unused]] AzFramework::EntitySpawnTicket& ticket,
|
||||
AzFramework::SpawnableConstEntityContainerView view)
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_idBatchMutex);
|
||||
m_spawnedEntityList.reserve(m_spawnedEntityList.size() + view.size());
|
||||
for (const AZ::Entity* entity : view)
|
||||
{
|
||||
m_spawnedEntityList.emplace_back(entity->GetId());
|
||||
}
|
||||
m_spawnBatchSizes.push_back(view.size());
|
||||
};
|
||||
|
||||
AzFramework::SpawnableEntitiesInterface::Get()->SpawnAllEntities(m_spawnTicket, preSpawnCB, spawnCompleteCB);
|
||||
m_spawnableAsset.SetAutoLoadBehavior(AZ::Data::AssetLoadBehavior::PreLoad);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpawnNodeable::RequestSpawn(Data::Vector3Type translation, Data::Vector3Type rotation, Data::NumberType scale)
|
||||
{
|
||||
if (!m_spawnableAsset.IsReady())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto preSpawnCB = [this, translation, rotation, scale]([[maybe_unused]] AzFramework::EntitySpawnTicket& ticket,
|
||||
AzFramework::SpawnableEntityContainerView view)
|
||||
{
|
||||
AZ::Entity* rootEntity = *view.begin();
|
||||
|
||||
AzFramework::TransformComponent* entityTransform =
|
||||
rootEntity->FindComponent<AzFramework::TransformComponent>();
|
||||
|
||||
if (entityTransform)
|
||||
{
|
||||
AZ::Vector3 rotationCopy = rotation;
|
||||
AZ::Quaternion rotationQuat = AZ::Quaternion::CreateFromEulerAnglesDegrees(rotationCopy);
|
||||
|
||||
entityTransform->SetWorldTM(AZ::Transform(translation, rotationQuat, AZ::Vector3(scale, scale, scale)));
|
||||
}
|
||||
};
|
||||
|
||||
auto spawnCompleteCB = [this]([[maybe_unused]] AzFramework::EntitySpawnTicket& ticket,
|
||||
AzFramework::SpawnableConstEntityContainerView view)
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_idBatchMutex);
|
||||
m_spawnedEntityList.reserve(m_spawnedEntityList.size() + view.size());
|
||||
for (const AZ::Entity* entity : view)
|
||||
{
|
||||
m_spawnedEntityList.emplace_back(entity->GetId());
|
||||
}
|
||||
m_spawnBatchSizes.push_back(view.size());
|
||||
};
|
||||
|
||||
AzFramework::SpawnableEntitiesInterface::Get()->SpawnAllEntities(m_spawnTicket, preSpawnCB, spawnCompleteCB);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,36 +22,31 @@
|
||||
#include <ScriptCanvas/Core/Node.h>
|
||||
#include <ScriptCanvas/Core/Nodeable.h>
|
||||
|
||||
namespace ScriptCanvas
|
||||
namespace ScriptCanvas::Nodeables::Spawning
|
||||
{
|
||||
namespace Nodeables
|
||||
class SpawnNodeable
|
||||
: public ScriptCanvas::Nodeable,
|
||||
public AZ::TickBus::Handler
|
||||
{
|
||||
namespace Spawning
|
||||
{
|
||||
class SpawnNodeable
|
||||
: public ScriptCanvas::Nodeable,
|
||||
public AZ::TickBus::Handler
|
||||
{
|
||||
SCRIPTCANVAS_NODE(SpawnNodeable);
|
||||
public:
|
||||
SpawnNodeable() = default;
|
||||
SpawnNodeable(const SpawnNodeable& rhs);
|
||||
SCRIPTCANVAS_NODE(SpawnNodeable);
|
||||
public:
|
||||
SpawnNodeable() = default;
|
||||
SpawnNodeable(const SpawnNodeable& rhs);
|
||||
SpawnNodeable& operator=(SpawnNodeable& rhs);
|
||||
|
||||
void OnInitializeExecutionState() override;
|
||||
void OnDeactivate() override;
|
||||
void OnInitializeExecutionState() override;
|
||||
void OnDeactivate() override;
|
||||
|
||||
//TickBus
|
||||
void OnTick(float delta, AZ::ScriptTimePoint timePoint) override;
|
||||
//TickBus
|
||||
void OnTick(float delta, AZ::ScriptTimePoint timePoint) override;
|
||||
|
||||
void OnSpawnAssetChanged();
|
||||
void OnSpawnAssetChanged();
|
||||
|
||||
private:
|
||||
AzFramework::EntitySpawnTicket m_spawnTicket;
|
||||
private:
|
||||
AzFramework::EntitySpawnTicket m_spawnTicket;
|
||||
|
||||
AZStd::vector<Data::EntityIDType> m_spawnedEntityList;
|
||||
AZStd::vector<size_t> m_spawnBatchSizes;
|
||||
AZStd::recursive_mutex m_idBatchMutex;
|
||||
};
|
||||
}
|
||||
}
|
||||
AZStd::vector<Data::EntityIDType> m_spawnedEntityList;
|
||||
AZStd::vector<size_t> m_spawnBatchSizes;
|
||||
AZStd::recursive_mutex m_idBatchMutex;
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user