{LYN-4514} Engine updates to enable PAB for the Blast Gem (#2140)
* {LYN-4514} Engine updates to enable PAB for the Blast Gem
* Engine updates to enable Python Asset Building for the Blast Gem
* added API to detect IsPythonActive()
* ExportProductList behavior
* scene manifest usage of generated assetinfo
* updated ScriptProcessorRuleBehavior to handle OnPrepareForExport
Tests: new tests for scene behavior via ExportProduct
Signed-off-by: Jackson <23512001+jackalbe@users.noreply.github.com>
* updated base on PR feedback
added more comments for IsPythonActive()
added a serializeContext for export product list
Signed-off-by: Jackson <23512001+jackalbe@users.noreply.github.com>
This commit is contained in:
@@ -25,213 +25,319 @@
|
||||
#include <SceneAPI/SceneCore/Containers/Views/PairIterator.h>
|
||||
#include <SceneAPI/SceneData/Rules/ScriptProcessorRule.h>
|
||||
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
|
||||
#include <SceneAPI/SceneCore/Events/ExportProductList.h>
|
||||
|
||||
namespace AZ
|
||||
namespace AZ::SceneAPI::Behaviors
|
||||
{
|
||||
namespace SceneAPI
|
||||
class EditorPythonConsoleNotificationHandler final
|
||||
: protected AzToolsFramework::EditorPythonConsoleNotificationBus::Handler
|
||||
{
|
||||
namespace Behaviors
|
||||
public:
|
||||
EditorPythonConsoleNotificationHandler()
|
||||
{
|
||||
class EditorPythonConsoleNotificationHandler final
|
||||
: protected AzToolsFramework::EditorPythonConsoleNotificationBus::Handler
|
||||
BusConnect();
|
||||
}
|
||||
|
||||
~EditorPythonConsoleNotificationHandler()
|
||||
{
|
||||
BusDisconnect();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AzToolsFramework::EditorPythonConsoleNotifications
|
||||
void OnTraceMessage([[maybe_unused]] AZStd::string_view message) override
|
||||
{
|
||||
using namespace AZ::SceneAPI::Utilities;
|
||||
AZ_TracePrintf(LogWindow, "%.*s \n", AZ_STRING_ARG(message));
|
||||
}
|
||||
|
||||
void OnErrorMessage([[maybe_unused]] AZStd::string_view message) override
|
||||
{
|
||||
using namespace AZ::SceneAPI::Utilities;
|
||||
AZ_TracePrintf(ErrorWindow, "[ERROR] %.*s \n", AZ_STRING_ARG(message));
|
||||
}
|
||||
|
||||
void OnExceptionMessage([[maybe_unused]] AZStd::string_view message) override
|
||||
{
|
||||
using namespace AZ::SceneAPI::Utilities;
|
||||
AZ_TracePrintf(ErrorWindow, "[EXCEPTION] %.*s \n", AZ_STRING_ARG(message));
|
||||
}
|
||||
};
|
||||
|
||||
using ExportProductList = AZ::SceneAPI::Events::ExportProductList;
|
||||
|
||||
// a event bus to signal during scene building
|
||||
struct ScriptBuildingNotifications
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
virtual AZStd::string OnUpdateManifest(Containers::Scene& scene) = 0;
|
||||
virtual ExportProductList OnPrepareForExport(
|
||||
const Containers::Scene& scene,
|
||||
AZStd::string_view outputDirectory,
|
||||
AZStd::string_view platformIdentifier,
|
||||
const ExportProductList& productList) = 0;
|
||||
};
|
||||
using ScriptBuildingNotificationBus = AZ::EBus<ScriptBuildingNotifications>;
|
||||
|
||||
// a back end to handle scene builder events for a script
|
||||
struct ScriptBuildingNotificationBusHandler final
|
||||
: public ScriptBuildingNotificationBus::Handler
|
||||
, public AZ::BehaviorEBusHandler
|
||||
{
|
||||
AZ_EBUS_BEHAVIOR_BINDER(
|
||||
ScriptBuildingNotificationBusHandler,
|
||||
"{DF2B51DE-A4D0-4139-B5D0-DF185832380D}",
|
||||
AZ::SystemAllocator,
|
||||
OnUpdateManifest,
|
||||
OnPrepareForExport);
|
||||
|
||||
virtual ~ScriptBuildingNotificationBusHandler() = default;
|
||||
|
||||
AZStd::string OnUpdateManifest(Containers::Scene& scene) override
|
||||
{
|
||||
AZStd::string result;
|
||||
CallResult(result, FN_OnUpdateManifest, scene);
|
||||
return result;
|
||||
}
|
||||
|
||||
ExportProductList OnPrepareForExport(
|
||||
const Containers::Scene& scene,
|
||||
AZStd::string_view outputDirectory,
|
||||
AZStd::string_view platformIdentifier,
|
||||
const ExportProductList& productList) override
|
||||
{
|
||||
ExportProductList result;
|
||||
CallResult(result, FN_OnPrepareForExport, scene, outputDirectory, platformIdentifier, productList);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
public:
|
||||
EditorPythonConsoleNotificationHandler()
|
||||
{
|
||||
BusConnect();
|
||||
}
|
||||
behaviorContext->EBus<ScriptBuildingNotificationBus>("ScriptBuildingNotificationBus")
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
|
||||
->Attribute(AZ::Script::Attributes::Module, "scene")
|
||||
->Handler<ScriptBuildingNotificationBusHandler>()
|
||||
->Event("OnUpdateManifest", &ScriptBuildingNotificationBus::Events::OnUpdateManifest)
|
||||
->Event("OnPrepareForExport", &ScriptBuildingNotificationBus::Events::OnPrepareForExport);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
~EditorPythonConsoleNotificationHandler()
|
||||
{
|
||||
BusDisconnect();
|
||||
}
|
||||
struct ScriptProcessorRuleBehavior::ExportEventHandler final
|
||||
: public AZ::SceneAPI::SceneCore::ExportingComponent
|
||||
{
|
||||
using PreExportEventContextFunction = AZStd::function<bool(Events::PreExportEventContext&)>;
|
||||
PreExportEventContextFunction m_preExportEventContextFunction;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AzToolsFramework::EditorPythonConsoleNotifications
|
||||
void OnTraceMessage([[maybe_unused]] AZStd::string_view message) override
|
||||
{
|
||||
using namespace AZ::SceneAPI::Utilities;
|
||||
AZ_TracePrintf(LogWindow, "%.*s \n", AZ_STRING_ARG(message));
|
||||
}
|
||||
ExportEventHandler(PreExportEventContextFunction preExportEventContextFunction)
|
||||
: m_preExportEventContextFunction(preExportEventContextFunction)
|
||||
{
|
||||
BindToCall(&ExportEventHandler::PrepareForExport);
|
||||
AZ::SceneAPI::SceneCore::ExportingComponent::Activate();
|
||||
}
|
||||
|
||||
void OnErrorMessage([[maybe_unused]] AZStd::string_view message) override
|
||||
{
|
||||
using namespace AZ::SceneAPI::Utilities;
|
||||
AZ_TracePrintf(ErrorWindow, "[ERROR] %.*s \n", AZ_STRING_ARG(message));
|
||||
}
|
||||
~ExportEventHandler()
|
||||
{
|
||||
AZ::SceneAPI::SceneCore::ExportingComponent::Deactivate();
|
||||
}
|
||||
|
||||
void OnExceptionMessage([[maybe_unused]] AZStd::string_view message) override
|
||||
{
|
||||
using namespace AZ::SceneAPI::Utilities;
|
||||
AZ_TracePrintf(ErrorWindow, "[EXCEPTION] %.*s \n", AZ_STRING_ARG(message));
|
||||
}
|
||||
};
|
||||
// this allows a Python script to add product assets on "scene export"
|
||||
Events::ProcessingResult PrepareForExport(Events::PreExportEventContext& context)
|
||||
{
|
||||
return m_preExportEventContextFunction(context) ? Events::ProcessingResult::Success : Events::ProcessingResult::Failure;
|
||||
}
|
||||
};
|
||||
|
||||
// a event bus to signal during scene building
|
||||
struct ScriptBuildingNotifications
|
||||
: public AZ::EBusTraits
|
||||
void ScriptProcessorRuleBehavior::Activate()
|
||||
{
|
||||
Events::AssetImportRequestBus::Handler::BusConnect();
|
||||
m_exportEventHandler = AZStd::make_shared<ExportEventHandler>([this](Events::PreExportEventContext& context)
|
||||
{
|
||||
return this->DoPrepareForExport(context);
|
||||
});
|
||||
}
|
||||
|
||||
void ScriptProcessorRuleBehavior::Deactivate()
|
||||
{
|
||||
m_exportEventHandler.reset();
|
||||
Events::AssetImportRequestBus::Handler::BusDisconnect();
|
||||
UnloadPython();
|
||||
}
|
||||
|
||||
bool ScriptProcessorRuleBehavior::LoadPython(const AZ::SceneAPI::Containers::Scene& scene)
|
||||
{
|
||||
if (m_editorPythonEventsInterface && !m_scriptFilename.empty())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// get project folder
|
||||
auto settingsRegistry = AZ::SettingsRegistry::Get();
|
||||
AZ::IO::FixedMaxPath projectPath;
|
||||
if (!settingsRegistry->Get(projectPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectPath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const AZ::SceneAPI::Containers::SceneManifest& manifest = scene.GetManifest();
|
||||
auto view = Containers::MakeDerivedFilterView<DataTypes::IScriptProcessorRule>(manifest.GetValueStorage());
|
||||
for (const auto& scriptItem : view)
|
||||
{
|
||||
AZ::IO::FixedMaxPath scriptFilename(scriptItem.GetScriptFilename());
|
||||
if (scriptFilename.empty())
|
||||
{
|
||||
virtual AZStd::string OnUpdateManifest(Containers::Scene& scene) = 0;
|
||||
};
|
||||
using ScriptBuildingNotificationBus = AZ::EBus<ScriptBuildingNotifications>;
|
||||
AZ_Warning("scene", false, "Skipping an empty script filename in (%s)", scene.GetManifestFilename().c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
// a back end to handle scene builder events for a script
|
||||
struct ScriptBuildingNotificationBusHandler final
|
||||
: public ScriptBuildingNotificationBus::Handler
|
||||
, public AZ::BehaviorEBusHandler
|
||||
// check for file exist via absolute path
|
||||
if (!IO::FileIOBase::GetInstance()->Exists(scriptFilename.c_str()))
|
||||
{
|
||||
AZ_EBUS_BEHAVIOR_BINDER(
|
||||
ScriptBuildingNotificationBusHandler,
|
||||
"{DF2B51DE-A4D0-4139-B5D0-DF185832380D}",
|
||||
AZ::SystemAllocator,
|
||||
OnUpdateManifest);
|
||||
|
||||
virtual ~ScriptBuildingNotificationBusHandler() = default;
|
||||
|
||||
AZStd::string OnUpdateManifest(Containers::Scene& scene) override
|
||||
// check for script in the project folder
|
||||
AZ::IO::FixedMaxPath projectScriptPath = projectPath / scriptFilename;
|
||||
if (!IO::FileIOBase::GetInstance()->Exists(projectScriptPath.c_str()))
|
||||
{
|
||||
AZStd::string result;
|
||||
CallResult(result, FN_OnUpdateManifest, scene);
|
||||
return result;
|
||||
AZ_Warning("scene", false, "Skipping a missing script (%s) in manifest file (%s)",
|
||||
scriptFilename.c_str(),
|
||||
scene.GetManifestFilename().c_str());
|
||||
continue;
|
||||
}
|
||||
scriptFilename = AZStd::move(projectScriptPath);
|
||||
}
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context)
|
||||
// lazy load the Python interface
|
||||
auto editorPythonEventsInterface = AZ::Interface<AzToolsFramework::EditorPythonEventsInterface>::Get();
|
||||
if (editorPythonEventsInterface->IsPythonActive() == false)
|
||||
{
|
||||
const bool silenceWarnings = false;
|
||||
if (editorPythonEventsInterface->StartPython(silenceWarnings) == false)
|
||||
{
|
||||
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->EBus<ScriptBuildingNotificationBus>("ScriptBuildingNotificationBus")
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
|
||||
->Attribute(AZ::Script::Attributes::Module, "scene")
|
||||
->Handler<ScriptBuildingNotificationBusHandler>()
|
||||
->Event("OnUpdateManifest", &ScriptBuildingNotificationBus::Events::OnUpdateManifest);
|
||||
}
|
||||
editorPythonEventsInterface = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// both Python and the script need to be ready
|
||||
if (editorPythonEventsInterface == nullptr || scriptFilename.empty())
|
||||
{
|
||||
AZ_Warning("scene", false,"The scene manifest (%s) attempted to use script(%s) but Python is not enabled;"
|
||||
"please add the EditorPythonBinding gem & PythonAssetBuilder gem to your project.",
|
||||
scene.GetManifestFilename().c_str(), scriptFilename.c_str());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_editorPythonEventsInterface = editorPythonEventsInterface;
|
||||
m_scriptFilename = scriptFilename.c_str();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ScriptProcessorRuleBehavior::UnloadPython()
|
||||
{
|
||||
if (m_editorPythonEventsInterface)
|
||||
{
|
||||
const bool silenceWarnings = true;
|
||||
m_editorPythonEventsInterface->StopPython(silenceWarnings);
|
||||
m_editorPythonEventsInterface = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool ScriptProcessorRuleBehavior::DoPrepareForExport(Events::PreExportEventContext& context)
|
||||
{
|
||||
using namespace AzToolsFramework;
|
||||
|
||||
auto executeCallback = [this, &context]()
|
||||
{
|
||||
// set up script's hook callback
|
||||
EditorPythonRunnerRequestBus::Broadcast(&EditorPythonRunnerRequestBus::Events::ExecuteByFilename,
|
||||
m_scriptFilename.c_str());
|
||||
|
||||
// call script's callback to allow extra products
|
||||
ExportProductList extraProducts;
|
||||
ScriptBuildingNotificationBus::BroadcastResult(extraProducts, &ScriptBuildingNotificationBus::Events::OnPrepareForExport,
|
||||
context.GetScene(),
|
||||
context.GetOutputDirectory(),
|
||||
context.GetPlatformIdentifier(),
|
||||
context.GetProductList()
|
||||
);
|
||||
|
||||
// add new products
|
||||
for (const auto& product : extraProducts.GetProducts())
|
||||
{
|
||||
context.GetProductList().AddProduct(
|
||||
product.m_filename,
|
||||
product.m_id,
|
||||
product.m_assetType,
|
||||
product.m_lod,
|
||||
product.m_subId,
|
||||
product.m_dependencyFlags);
|
||||
}
|
||||
};
|
||||
|
||||
if (LoadPython(context.GetScene()))
|
||||
{
|
||||
EditorPythonConsoleNotificationHandler logger;
|
||||
m_editorPythonEventsInterface->ExecuteWithLock(executeCallback);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScriptProcessorRuleBehavior::Reflect(ReflectContext* context)
|
||||
{
|
||||
ScriptBuildingNotificationBusHandler::Reflect(context);
|
||||
|
||||
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<ScriptProcessorRuleBehavior, BehaviorComponent>()->Version(1);
|
||||
}
|
||||
}
|
||||
|
||||
Events::ProcessingResult ScriptProcessorRuleBehavior::UpdateManifest(
|
||||
Containers::Scene& scene,
|
||||
Events::AssetImportRequest::ManifestAction action,
|
||||
[[maybe_unused]] Events::AssetImportRequest::RequestingApplication requester)
|
||||
{
|
||||
using namespace AzToolsFramework;
|
||||
|
||||
if (action != ManifestAction::Update)
|
||||
{
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
if (LoadPython(scene))
|
||||
{
|
||||
AZStd::string manifestUpdate;
|
||||
auto executeCallback = [this, &scene, &manifestUpdate]()
|
||||
{
|
||||
EditorPythonRunnerRequestBus::Broadcast(&EditorPythonRunnerRequestBus::Events::ExecuteByFilename,
|
||||
m_scriptFilename.c_str());
|
||||
|
||||
ScriptBuildingNotificationBus::BroadcastResult(manifestUpdate, &ScriptBuildingNotificationBus::Events::OnUpdateManifest,
|
||||
scene);
|
||||
};
|
||||
|
||||
void ScriptProcessorRuleBehavior::Activate()
|
||||
EditorPythonConsoleNotificationHandler logger;
|
||||
m_editorPythonEventsInterface->ExecuteWithLock(executeCallback);
|
||||
|
||||
// attempt to load the manifest string back to a JSON-scene-manifest
|
||||
auto sceneManifestLoader = AZStd::make_unique<AZ::SceneAPI::Containers::SceneManifest>();
|
||||
auto loadOutcome = sceneManifestLoader->LoadFromString(manifestUpdate);
|
||||
if (loadOutcome.IsSuccess())
|
||||
{
|
||||
Events::AssetImportRequestBus::Handler::BusConnect();
|
||||
scene.GetManifest().Clear();
|
||||
for (size_t entryIndex = 0; entryIndex < sceneManifestLoader->GetEntryCount(); ++entryIndex)
|
||||
{
|
||||
scene.GetManifest().AddEntry(sceneManifestLoader->GetValue(entryIndex));
|
||||
}
|
||||
return Events::ProcessingResult::Success;
|
||||
}
|
||||
}
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
void ScriptProcessorRuleBehavior::Deactivate()
|
||||
{
|
||||
Events::AssetImportRequestBus::Handler::BusDisconnect();
|
||||
if (m_editorPythonEventsInterface)
|
||||
{
|
||||
const bool silenceWarnings = true;
|
||||
m_editorPythonEventsInterface->StopPython(silenceWarnings);
|
||||
m_editorPythonEventsInterface = nullptr;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptProcessorRuleBehavior::Reflect(ReflectContext* context)
|
||||
{
|
||||
ScriptBuildingNotificationBusHandler::Reflect(context);
|
||||
|
||||
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<ScriptProcessorRuleBehavior, BehaviorComponent>()->Version(1);
|
||||
}
|
||||
}
|
||||
|
||||
Events::ProcessingResult ScriptProcessorRuleBehavior::UpdateManifest(
|
||||
Containers::Scene& scene,
|
||||
Events::AssetImportRequest::ManifestAction action,
|
||||
[[maybe_unused]] Events::AssetImportRequest::RequestingApplication requester)
|
||||
{
|
||||
using namespace AzToolsFramework;
|
||||
|
||||
if (action != ManifestAction::Update)
|
||||
{
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
// get project folder
|
||||
auto settingsRegistry = AZ::SettingsRegistry::Get();
|
||||
AZ::IO::FixedMaxPath projectPath;
|
||||
if (!settingsRegistry->Get(projectPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectPath))
|
||||
{
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
auto& sceneManifest = scene.GetManifest();
|
||||
auto view = Containers::MakeDerivedFilterView<DataTypes::IScriptProcessorRule>(sceneManifest.GetValueStorage());
|
||||
for (const auto& scriptItem : view)
|
||||
{
|
||||
AZ::IO::FixedMaxPath scriptFilename(scriptItem.GetScriptFilename());
|
||||
if (scriptFilename.empty())
|
||||
{
|
||||
AZ_Warning("scene", false, "Skipping an empty script filename in (%s)", scene.GetManifestFilename().c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
// check for file exist via absolute path
|
||||
if (!IO::FileIOBase::GetInstance()->Exists(scriptFilename.c_str()))
|
||||
{
|
||||
// check for script in the project folder
|
||||
AZ::IO::FixedMaxPath projectScriptPath = projectPath / scriptFilename;
|
||||
if (!IO::FileIOBase::GetInstance()->Exists(projectScriptPath.c_str()))
|
||||
{
|
||||
AZ_Warning("scene", false, "Skipping a missing script (%s) in manifest file (%s)",
|
||||
scriptFilename.c_str(),
|
||||
scene.GetManifestFilename().c_str());
|
||||
|
||||
continue;
|
||||
}
|
||||
scriptFilename = AZStd::move(projectScriptPath);
|
||||
}
|
||||
|
||||
// lazy load the Python interface
|
||||
if (!m_editorPythonEventsInterface)
|
||||
{
|
||||
m_editorPythonEventsInterface = AZ::Interface<AzToolsFramework::EditorPythonEventsInterface>::Get();
|
||||
const bool silenceWarnings = true;
|
||||
m_editorPythonEventsInterface->StartPython(silenceWarnings);
|
||||
}
|
||||
|
||||
if (!m_editorPythonEventsInterface && !scriptFilename.empty())
|
||||
{
|
||||
AZ_Warning("scene", false,
|
||||
"The scene manifest (%s) attempted to use script(%s) but Python is not enabled;"
|
||||
"please add the EditorPythonBinding gem & PythonAssetBuilder gem to your project.",
|
||||
scene.GetManifestFilename().c_str(), scriptFilename.c_str());
|
||||
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
AZStd::string manifestUpdate;
|
||||
auto executeCallback = [&scene, &scriptFilename, &manifestUpdate]()
|
||||
{
|
||||
EditorPythonRunnerRequestBus::Broadcast(
|
||||
&EditorPythonRunnerRequestBus::Events::ExecuteByFilename,
|
||||
scriptFilename.c_str());
|
||||
|
||||
ScriptBuildingNotificationBus::BroadcastResult(
|
||||
manifestUpdate,
|
||||
&ScriptBuildingNotificationBus::Events::OnUpdateManifest,
|
||||
scene);
|
||||
};
|
||||
EditorPythonConsoleNotificationHandler logger;
|
||||
m_editorPythonEventsInterface->ExecuteWithLock(executeCallback);
|
||||
|
||||
// attempt to load the manifest string back to a JSON-scene-manifest
|
||||
auto sceneManifestLoader = AZStd::make_unique<AZ::SceneAPI::Containers::SceneManifest>();
|
||||
auto loadOutcome = sceneManifestLoader->LoadFromString(manifestUpdate);
|
||||
if (loadOutcome.IsSuccess())
|
||||
{
|
||||
sceneManifest.Clear();
|
||||
for (size_t entryIndex = 0; entryIndex < sceneManifestLoader->GetEntryCount(); ++entryIndex)
|
||||
{
|
||||
sceneManifest.AddEntry(sceneManifestLoader->GetValue(entryIndex));
|
||||
}
|
||||
return Events::ProcessingResult::Success;
|
||||
}
|
||||
}
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
} // namespace Behaviors
|
||||
} // namespace SceneAPI
|
||||
} // namespace AZ
|
||||
|
||||
Reference in New Issue
Block a user