Add asset picker support to spawn SC node and thread safety measures

This commit is contained in:
sconel
2021-05-26 16:45:04 -07:00
parent 58afb79060
commit b5599ca739
9 changed files with 158 additions and 30 deletions
@@ -7,6 +7,7 @@
Base="ScriptCanvas::Nodeable"
Icon="Icons/ScriptCanvas/Placeholder.png"
Category="Spawning"
Version="0"
GeneratePropertyFriend="True"
Namespace="ScriptCanvas"
Description="Spawn">
@@ -21,5 +22,17 @@
<Parameter Name="SpawnedEntitiesList" Type="AZStd::vector&lt;Data::EntityIDType&gt;" Description="List of spawned entities sorted by hiearchy with the root being first"/>
</Output>/>
<Property Name ="m_spawnableAsset" Type="AZ::Data::Asset&lt;AzFramework::Spawnable&gt;" Serialize="true">
<PropertyData Name="Prefab Asset"
Description="Prefab source asset to spawn."
Serialize="true"
UIHandler="AZ::Edit::UIHandlers::Default">
<EditAttribute Key="AZ::Edit::Attributes::ShowProductAssetFileName" Value="false"/>
<EditAttribute Key="AZ::Edit::Attributes::HideProductFilesInAssetPicker" Value="true"/>
<EditAttribute Key="AZ::Edit::Attributes::AssetPickerTitle" Value="&quot;a Prefab&quot;"/>
<EditAttribute Key="AZ::Edit::Attributes::ChangeNotify" Value="&amp;SpawnNodeable::OnSpawnAssetChanged"/>
</PropertyData>
</Property>
</Class>
</ScriptCanvas>
@@ -14,6 +14,7 @@
#include <ScriptCanvas/Libraries/Spawning/SpawnNodeable.h>
#include <AzFramework/Components/TransformComponent.h>
#include <AzFramework/Spawnable/SpawnableAssetHandler.h>
namespace ScriptCanvas
{
@@ -23,9 +24,6 @@ namespace ScriptCanvas
{
SpawnNodeable::SpawnNodeable()
{
AZ::Data::AssetId cubeAssetId("{90552CB9-2F29-5A2E-976C-61BF7ADACB81}", 272062881);
m_spawnableAsset = AZ::Data::AssetManager::Instance().GetAsset<AzFramework::Spawnable>(cubeAssetId, AZ::Data::AssetLoadBehavior::PreLoad);
AZ::Data::AssetManager::Instance().BlockUntilLoadComplete(m_spawnableAsset);
}
SpawnNodeable::SpawnNodeable(const SpawnNodeable& rhs)
@@ -35,35 +33,85 @@ namespace ScriptCanvas
void SpawnNodeable::OnInitializeExecutionState()
{
if (!AZ::TickBus::Handler::BusIsConnected())
{
AZ::TickBus::Handler::BusConnect();
}
m_spawnTicket.IsValid();
m_spawnTicket = AzFramework::EntitySpawnTicket(m_spawnableAsset);
}
void SpawnNodeable::OnDeactivate()
{
if (AZ::TickBus::Handler::BusIsConnected())
{
AZ::TickBus::Handler::BusDisconnect();
}
m_spawnTicket = AzFramework::EntitySpawnTicket();
}
//void SpawnNodeable::Translation(Data::Vector3Type translation)
//{
// m_translation = translation;
//}
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_recursiveMutex);
//void SpawnNodeable::Rotation(Data::Vector3Type rotation)
//{
// m_rotation = rotation;
//}
swappedSpawnedEntityList.swap(m_spawnedEntityList);
swappedSpawnBatchSizes.swap(m_spawnBatchSizes);
}
//void SpawnNodeable::Scale(Data::Vector3Type scale)
//{
// m_scale = scale;
//}
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);
}
}
}
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 =
@@ -81,15 +129,13 @@ namespace ScriptCanvas
auto spawnCompleteCB = [this]([[maybe_unused]] AzFramework::EntitySpawnTicket& ticket,
AzFramework::SpawnableConstEntityContainerView view)
{
AZStd::vector<Data::EntityIDType> spawnedEntities;
spawnedEntities.resize(view.size());
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_recursiveMutex);
m_spawnedEntityList.reserve(m_spawnedEntityList.size() + view.size());
for (const AZ::Entity* entity : view)
{
spawnedEntities.emplace_back(entity->GetId());
m_spawnedEntityList.emplace_back(entity->GetId());
}
CallOnSpawn(spawnedEntities);
m_spawnBatchSizes.push_back(view.size());
};
AzFramework::SpawnableEntitiesInterface::Get()->SpawnAllEntities(m_spawnTicket, preSpawnCB, spawnCompleteCB);
@@ -14,7 +14,10 @@
#include <Include/ScriptCanvas/Libraries/Spawning/SpawnNodeable.generated.h>
#include <AzCore/Component/TickBus.h>
#include <AzFramework/Spawnable/SpawnableEntitiesInterface.h>
#include <ScriptCanvas/CodeGen/NodeableCodegen.h>
#include <ScriptCanvas/Core/Node.h>
#include <ScriptCanvas/Core/Nodeable.h>
@@ -26,21 +29,28 @@ namespace ScriptCanvas
namespace Spawning
{
class SpawnNodeable
: public ScriptCanvas::Nodeable
: public ScriptCanvas::Nodeable,
public AZ::TickBus::Handler
{
SCRIPTCANVAS_NODE(SpawnNodeable);
public:
SpawnNodeable();
SpawnNodeable(const SpawnNodeable& rhs);
void OnInitializeExecutionState() override;
void OnDeactivate() override;
//TickBus
void OnTick(float delta, AZ::ScriptTimePoint timePoint) override;
void OnSpawnAssetChanged();
private:
AZ::Data::Asset<AzFramework::Spawnable> m_spawnableAsset;
AzFramework::EntitySpawnTicket m_spawnTicket;
AZStd::vector<Data::EntityIDType> m_spawnedEntityList;
AZStd::vector<size_t> m_spawnBatchSizes;
AZStd::recursive_mutex m_recursiveMutex;
};
}
}