3
0

BlendSpaceMotionContainerHandler.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <EMotionFX/Source/AnimGraphManager.h>
  9. #include <EMotionFX/Source/BlendSpaceManager.h>
  10. #include <EMotionFX/Source/EMotionFXManager.h>
  11. #include <EMotionFX/CommandSystem/Source/CommandManager.h>
  12. #include <EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/EMStudioManager.h>
  13. #include <EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/MotionSetSelectionWindow.h>
  14. #include <Editor/PropertyWidgets/BlendSpaceMotionContainerHandler.h>
  15. #include <Editor/AnimGraphEditorBus.h>
  16. #include <QHBoxLayout>
  17. #include <QMessageBox>
  18. #include <QLabel>
  19. #include <QPushButton>
  20. namespace EMotionFX
  21. {
  22. AZ_CLASS_ALLOCATOR_IMPL(BlendSpaceMotionWidget, EditorAllocator)
  23. AZ_CLASS_ALLOCATOR_IMPL(BlendSpaceMotionContainerWidget, EditorAllocator)
  24. AZ_CLASS_ALLOCATOR_IMPL(BlendSpaceMotionContainerHandler, EditorAllocator)
  25. BlendSpaceMotionWidget::BlendSpaceMotionWidget(BlendSpaceNode::BlendSpaceMotion* motion, QGridLayout* layout, int row)
  26. : m_motion(motion)
  27. {
  28. const AZStd::string& motionId = motion->GetMotionId();
  29. const bool showYFields = motion->GetDimension() == 2;
  30. int column = 0;
  31. // Motion name
  32. m_labelMotion = new QLabel(motionId.c_str());
  33. m_labelMotion->setObjectName("m_labelMotion");
  34. m_labelMotion->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
  35. layout->addWidget(m_labelMotion, row, column);
  36. column++;
  37. const auto makeSpinbox = [row, &column, layout, motionId = motionId.c_str()](const QString& text, const QString& color)
  38. {
  39. auto* axisLayout = new QHBoxLayout();
  40. axisLayout->setAlignment(Qt::AlignRight);
  41. auto* axisLabel = new QLabel(text);
  42. axisLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
  43. axisLabel->setStyleSheet(QString("QLabel { font-weight: bold; color : %1; }").arg(color));
  44. axisLayout->addWidget(axisLabel);
  45. auto* spinbox = new AzQtComponents::DoubleSpinBox();
  46. spinbox->setSingleStep(0.1);
  47. spinbox->setDecimals(4);
  48. spinbox->setRange(-FLT_MAX, FLT_MAX);
  49. spinbox->setProperty("motionId", motionId);
  50. spinbox->setKeyboardTracking(false);
  51. axisLayout->addWidget(spinbox);
  52. layout->addLayout(axisLayout, row, column);
  53. column++;
  54. return spinbox;
  55. };
  56. // Motion coordinate spinboxes.
  57. m_spinboxX = makeSpinbox("X", "red");
  58. if (showYFields)
  59. {
  60. m_spinboxY = makeSpinbox("Y", "green");
  61. }
  62. else
  63. {
  64. m_spinboxY = nullptr;
  65. }
  66. // Restore button.
  67. const int iconSize = 20;
  68. m_restoreButton = new QPushButton();
  69. m_restoreButton->setToolTip("Restore value to automatically computed one");
  70. m_restoreButton->setMinimumSize(iconSize, iconSize);
  71. m_restoreButton->setMaximumSize(iconSize, iconSize);
  72. m_restoreButton->setIcon(QIcon(":/EMotionFX/Restore.svg"));
  73. m_restoreButton->setProperty("motionId", motionId.c_str());
  74. layout->addWidget(m_restoreButton, row, column);
  75. column++;
  76. // Remove motion from blend space button.
  77. m_removeButton = new QPushButton();
  78. m_removeButton->setToolTip("Remove motion from blend space");
  79. m_removeButton->setMinimumSize(iconSize, iconSize);
  80. m_removeButton->setMaximumSize(iconSize, iconSize);
  81. m_removeButton->setIcon(QIcon(":/EMotionFX/Trash.svg"));
  82. layout->addWidget(m_removeButton, row, column);
  83. }
  84. void BlendSpaceMotionWidget::UpdateInterface(EMotionFX::BlendSpaceNode* blendSpaceNode, EMotionFX::AnimGraphInstance* animGraphInstance)
  85. {
  86. bool positionsComputed = false;
  87. AZ::Vector2 computedPosition = AZ::Vector2::CreateZero();
  88. if (blendSpaceNode && animGraphInstance)
  89. {
  90. blendSpaceNode->ComputeMotionCoordinates(m_motion->GetMotionId(), animGraphInstance, computedPosition);
  91. positionsComputed = true;
  92. }
  93. // Spinbox X
  94. m_spinboxX->blockSignals(true);
  95. if (m_motion->IsXCoordinateSetByUser())
  96. {
  97. m_spinboxX->setValue(m_motion->GetXCoordinate());
  98. }
  99. else
  100. {
  101. m_spinboxX->setValue(computedPosition.GetX());
  102. }
  103. m_spinboxX->blockSignals(false);
  104. m_spinboxX->setEnabled(m_motion->IsXCoordinateSetByUser() || positionsComputed);
  105. // Spinbox Y
  106. if (m_spinboxY)
  107. {
  108. m_spinboxY->blockSignals(true);
  109. if (m_motion->IsYCoordinateSetByUser())
  110. {
  111. m_spinboxY->setValue(m_motion->GetYCoordinate());
  112. }
  113. else
  114. {
  115. m_spinboxY->setValue(computedPosition.GetY());
  116. }
  117. m_spinboxY->blockSignals(false);
  118. m_spinboxY->setEnabled(m_motion->IsYCoordinateSetByUser() || positionsComputed);
  119. }
  120. // Enable the restore button in case the user manually set any of the.
  121. const bool enableRestoreButton = m_motion->IsXCoordinateSetByUser() || m_motion->IsYCoordinateSetByUser();
  122. m_restoreButton->setEnabled(enableRestoreButton);
  123. // is motion invalid?
  124. if (m_motion->TestFlag(EMotionFX::BlendSpaceNode::BlendSpaceMotion::TypeFlags::InvalidMotion))
  125. {
  126. m_labelMotion->setStyleSheet("#m_labelMotion { border: 1px solid red; }");
  127. m_labelMotion->setToolTip("Invalid motion.Select a motion set that contains this motion or add it to the current one.");
  128. }
  129. else
  130. {
  131. m_labelMotion->setStyleSheet("#m_labelMotion { border: none; }");
  132. m_labelMotion->setToolTip("");
  133. }
  134. }
  135. //---------------------------------------------------------------------------------------------------------------------------------------------------------
  136. BlendSpaceMotionContainerWidget::BlendSpaceMotionContainerWidget([[maybe_unused]] BlendSpaceNode* blendSpaceNode, QWidget* parent)
  137. : QWidget(parent)
  138. , m_blendSpaceNode(nullptr)
  139. , m_containerWidget(nullptr)
  140. , m_addMotionsLabel(nullptr)
  141. {
  142. QVBoxLayout* mainLayout = new QVBoxLayout();
  143. mainLayout->setSpacing(0);
  144. mainLayout->setMargin(0);
  145. setLayout(mainLayout);
  146. }
  147. void BlendSpaceMotionContainerWidget::SetBlendSpaceNode(BlendSpaceNode* blendSpaceNode)
  148. {
  149. m_blendSpaceNode = blendSpaceNode;
  150. ReInit();
  151. }
  152. void BlendSpaceMotionContainerWidget::SetMotions(const AZStd::vector<BlendSpaceNode::BlendSpaceMotion>& motions)
  153. {
  154. m_motions = motions;
  155. ReInit();
  156. }
  157. const AZStd::vector<BlendSpaceNode::BlendSpaceMotion>& BlendSpaceMotionContainerWidget::GetMotions() const
  158. {
  159. return m_motions;
  160. }
  161. BlendSpaceMotionWidget* BlendSpaceMotionContainerWidget::FindWidgetByMotionId(const AZStd::string& motionId) const
  162. {
  163. for (BlendSpaceMotionWidget* container : m_motionWidgets)
  164. {
  165. const BlendSpaceNode::BlendSpaceMotion* motion = container->m_motion;
  166. if (motion->GetMotionId() == motionId)
  167. {
  168. return container;
  169. }
  170. }
  171. return nullptr;
  172. }
  173. BlendSpaceMotionWidget* BlendSpaceMotionContainerWidget::FindWidget(QObject* object)
  174. {
  175. const AZStd::string motionId = object->property("motionId").toString().toUtf8().data();
  176. BlendSpaceMotionWidget* widget = FindWidgetByMotionId(motionId);
  177. AZ_Assert(widget, "Can't find widget for motion with id '%s'.", motionId.c_str());
  178. return widget;
  179. }
  180. void BlendSpaceMotionContainerWidget::OnAddMotion()
  181. {
  182. EMotionFX::MotionSet* motionSet = nullptr;
  183. AnimGraphEditorRequestBus::BroadcastResult(motionSet, &AnimGraphEditorRequests::GetSelectedMotionSet);
  184. if (!motionSet)
  185. {
  186. QMessageBox::warning(this, "No Motion Set", "Cannot open motion selection window. Please make sure exactly one motion set is selected.");
  187. return;
  188. }
  189. // Create and show the motion picker window.
  190. EMStudio::MotionSetSelectionWindow motionPickWindow(this);
  191. motionPickWindow.GetHierarchyWidget()->SetSelectionMode(false);
  192. motionPickWindow.Update(motionSet);
  193. motionPickWindow.setModal(true);
  194. if (motionPickWindow.exec() == QDialog::Rejected) // we pressed cancel or the close cross
  195. {
  196. return;
  197. }
  198. const AZStd::vector<AZStd::string> selectedMotionIds = motionPickWindow.GetHierarchyWidget()->GetSelectedMotionIds(motionSet);
  199. if (selectedMotionIds.empty())
  200. {
  201. return;
  202. }
  203. for (const AZStd::string& selectedMotionId : selectedMotionIds)
  204. {
  205. bool alreadyExists = false;
  206. for (const BlendSpaceNode::BlendSpaceMotion& blendSpaceMotion : m_motions)
  207. {
  208. if (blendSpaceMotion.GetMotionId() == selectedMotionId)
  209. {
  210. alreadyExists = true;
  211. break;
  212. }
  213. }
  214. if (!alreadyExists)
  215. {
  216. BlendSpaceNode::BlendSpaceMotion newMotion(selectedMotionId);
  217. m_motions.emplace_back(BlendSpaceNode::BlendSpaceMotion(selectedMotionId));
  218. }
  219. }
  220. m_blendSpaceNode->SetMotions(m_motions);
  221. m_motions = m_blendSpaceNode->GetMotions();
  222. ReInit();
  223. emit MotionsChanged();
  224. }
  225. void BlendSpaceMotionContainerWidget::OnRemoveMotion(const BlendSpaceNode::BlendSpaceMotion* motion)
  226. {
  227. // Iterate through the arributes back to front and delete the ones with the motion id from the delete button.
  228. // Note: Normally there should only be once instance as motion ids should be unique within this array.
  229. const AZ::s64 motionCount = m_motions.size();
  230. for (AZ::s64 i = motionCount - 1; i >= 0; i--)
  231. {
  232. if (&m_motions[i] == motion)
  233. {
  234. m_motions.erase(m_motions.begin() + i);
  235. }
  236. }
  237. ReInit();
  238. emit MotionsChanged();
  239. }
  240. void BlendSpaceMotionContainerWidget::OnPositionXChanged(double value)
  241. {
  242. UpdateMotionPosition(sender(), static_cast<float>(value), true, false);
  243. }
  244. void BlendSpaceMotionContainerWidget::OnPositionYChanged(double value)
  245. {
  246. UpdateMotionPosition(sender(), static_cast<float>(value), false, true);
  247. }
  248. // Get the currently active anim graph instance in case only exactly one actor instance is selected.
  249. EMotionFX::AnimGraphInstance* BlendSpaceMotionContainerWidget::GetSingleSelectedAnimGraphInstance() const
  250. {
  251. if (!m_blendSpaceNode)
  252. {
  253. return nullptr;
  254. }
  255. EMotionFX::ActorInstance* actorInstance = CommandSystem::GetCommandManager()->GetCurrentSelection().GetSingleActorInstance();
  256. if (!actorInstance)
  257. {
  258. return nullptr;
  259. }
  260. EMotionFX::AnimGraphInstance* animGraphInstance = actorInstance->GetAnimGraphInstance();
  261. if (animGraphInstance && animGraphInstance->GetAnimGraph() != m_blendSpaceNode->GetAnimGraph())
  262. {
  263. // The currently activated anim graph in the plugin differs from the one the current actor instance uses.
  264. animGraphInstance = nullptr;
  265. }
  266. return animGraphInstance;
  267. }
  268. void BlendSpaceMotionContainerWidget::UpdateMotionPosition(QObject* object, float value, bool updateX, bool updateY)
  269. {
  270. BlendSpaceMotionWidget* widget = FindWidget(object);
  271. if (!widget)
  272. {
  273. AZ_Error("EMotionFX", false, "Cannot update motion position. Can't find widget for QObject.");
  274. return;
  275. }
  276. BlendSpaceNode::BlendSpaceMotion* blendSpaceMotion = widget->m_motion;
  277. if (!blendSpaceMotion)
  278. {
  279. AZ_Error("EMotionFX", false, "Cannot update motion position. Blend space motion widget does not have a motion assigned to it.");
  280. return;
  281. }
  282. // Get the anim graph instance in case only exactly one actor instance is selected.
  283. EMotionFX::AnimGraphInstance* animGraphInstance = GetSingleSelectedAnimGraphInstance();
  284. if (animGraphInstance)
  285. {
  286. // Compute the position of the motion using the set evaluators.
  287. AZ::Vector2 computedPosition;
  288. m_blendSpaceNode->ComputeMotionCoordinates(blendSpaceMotion->GetMotionId(), animGraphInstance, computedPosition);
  289. const float epsilon = 1.0f / (powf(10, static_cast<float>(widget->m_spinboxX->decimals())));
  290. if (updateX)
  291. {
  292. if (blendSpaceMotion->IsXCoordinateSetByUser())
  293. {
  294. // If we already manually set the motion position, just update the x coordinate.
  295. blendSpaceMotion->SetXCoordinate(value);
  296. }
  297. else
  298. {
  299. // Check if the user just clicked the interface and triggered a value change or if he actually changed the value.
  300. if (!AZ::IsClose(computedPosition.GetX(), value, epsilon))
  301. {
  302. // Mark the position as manually set in case the user entered a new position that differs from the automatically computed one.
  303. blendSpaceMotion->MarkXCoordinateSetByUser(true);
  304. blendSpaceMotion->SetXCoordinate(value);
  305. }
  306. }
  307. }
  308. if (updateY)
  309. {
  310. if (blendSpaceMotion->IsYCoordinateSetByUser())
  311. {
  312. blendSpaceMotion->SetYCoordinate(value);
  313. }
  314. else
  315. {
  316. if (!AZ::IsClose(computedPosition.GetY(), value, epsilon))
  317. {
  318. blendSpaceMotion->MarkYCoordinateSetByUser(true);
  319. blendSpaceMotion->SetYCoordinate(value);
  320. }
  321. }
  322. }
  323. }
  324. else
  325. {
  326. // In case there is no character, only the motion positions that are already in manual mode are enabled.
  327. // Thus, we can just forward the position shown in the interface to the attribute.
  328. if (updateX)
  329. {
  330. blendSpaceMotion->MarkXCoordinateSetByUser(true);
  331. blendSpaceMotion->SetXCoordinate(value);
  332. }
  333. if (updateY)
  334. {
  335. blendSpaceMotion->MarkYCoordinateSetByUser(true);
  336. blendSpaceMotion->SetYCoordinate(value);
  337. }
  338. }
  339. ReInit();
  340. emit MotionsChanged();
  341. }
  342. void BlendSpaceMotionContainerWidget::OnRestorePosition()
  343. {
  344. BlendSpaceMotionWidget* widget = FindWidget(sender());
  345. if (!widget)
  346. {
  347. AZ_Error("EMotionFX", false, "Cannot update motion position. Can't find widget for QObject.");
  348. return;
  349. }
  350. // Get the anim graph instance in case only exactly one actor instance is selected.
  351. EMotionFX::AnimGraphInstance* animGraphInstance = GetSingleSelectedAnimGraphInstance();
  352. // Get access to the blend space node of the anim graph to be able to calculate the blend space position.
  353. if (m_blendSpaceNode && animGraphInstance)
  354. {
  355. m_blendSpaceNode->RestoreMotionCoordinates(*widget->m_motion, animGraphInstance);
  356. ReInit();
  357. emit MotionsChanged();
  358. }
  359. }
  360. void BlendSpaceMotionContainerWidget::UpdateInterface()
  361. {
  362. // Get the anim graph instance in case only exactly one actor instance is selected.
  363. EMotionFX::AnimGraphInstance* animGraphInstance = GetSingleSelectedAnimGraphInstance();
  364. for (BlendSpaceMotionWidget* widget : m_motionWidgets)
  365. {
  366. widget->UpdateInterface(m_blendSpaceNode, animGraphInstance);
  367. }
  368. if (m_motions.empty())
  369. {
  370. m_addMotionsLabel->setText("Add motions and set coordinates.");
  371. }
  372. else
  373. {
  374. m_addMotionsLabel->setText("");
  375. }
  376. }
  377. void BlendSpaceMotionContainerWidget::ReInit()
  378. {
  379. if (m_containerWidget)
  380. {
  381. // Hide the old widget and request deletion.
  382. m_containerWidget->hide();
  383. m_containerWidget->deleteLater();
  384. m_containerWidget = nullptr;
  385. m_addMotionsLabel = nullptr;
  386. m_motionWidgets.clear();
  387. }
  388. m_containerWidget = new QWidget();
  389. m_containerWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
  390. QVBoxLayout* widgetLayout = new QVBoxLayout();
  391. QHBoxLayout* topRowLayout = new QHBoxLayout();
  392. // Add helper label left of the add button.
  393. m_addMotionsLabel = new QLabel();
  394. topRowLayout->addWidget(m_addMotionsLabel, 0, Qt::AlignLeft);
  395. // Add motions button.
  396. QPushButton* addMotionsButton = new QPushButton();
  397. EMStudio::EMStudioManager::MakeTransparentButton(addMotionsButton, "Images/Icons/Plus.svg", "Add motions to blend space");
  398. connect(addMotionsButton, &QPushButton::clicked, this, &BlendSpaceMotionContainerWidget::OnAddMotion);
  399. topRowLayout->addWidget(addMotionsButton, 0, Qt::AlignRight);
  400. widgetLayout->addLayout(topRowLayout);
  401. if (!m_motions.empty())
  402. {
  403. QWidget* motionsWidget = new QWidget(m_containerWidget);
  404. motionsWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
  405. QGridLayout* motionsLayout = new QGridLayout();
  406. motionsLayout->setMargin(0);
  407. const size_t motionCount = m_motions.size();
  408. for (size_t i = 0; i < motionCount; ++i)
  409. {
  410. BlendSpaceNode::BlendSpaceMotion* blendSpaceMotion = &m_motions[i];
  411. BlendSpaceMotionWidget* motionWidget = new BlendSpaceMotionWidget(blendSpaceMotion, motionsLayout, static_cast<int>(i));
  412. connect(motionWidget->m_spinboxX, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &EMotionFX::BlendSpaceMotionContainerWidget::OnPositionXChanged);
  413. if (motionWidget->m_spinboxY)
  414. {
  415. connect(motionWidget->m_spinboxY, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &EMotionFX::BlendSpaceMotionContainerWidget::OnPositionYChanged);
  416. }
  417. connect(motionWidget->m_restoreButton, &QPushButton::clicked, this, &BlendSpaceMotionContainerWidget::OnRestorePosition);
  418. connect(motionWidget->m_removeButton, &QPushButton::clicked, [this, blendSpaceMotion]()
  419. {
  420. OnRemoveMotion(blendSpaceMotion);
  421. });
  422. m_motionWidgets.emplace_back(motionWidget);
  423. }
  424. motionsWidget->setLayout(motionsLayout);
  425. widgetLayout->addWidget(motionsWidget);
  426. }
  427. m_containerWidget->setLayout(widgetLayout);
  428. layout()->addWidget(m_containerWidget);
  429. UpdateInterface();
  430. }
  431. //---------------------------------------------------------------------------------------------------------------------------------------------------------
  432. BlendSpaceMotionContainerHandler::BlendSpaceMotionContainerHandler()
  433. : QObject()
  434. , AzToolsFramework::PropertyHandler<AZStd::vector<BlendSpaceNode::BlendSpaceMotion>, BlendSpaceMotionContainerWidget>()
  435. , m_blendSpaceNode(nullptr)
  436. {
  437. }
  438. AZ::u32 BlendSpaceMotionContainerHandler::GetHandlerName() const
  439. {
  440. return AZ_CRC("BlendSpaceMotionContainer", 0x8025d37d);
  441. }
  442. QWidget* BlendSpaceMotionContainerHandler::CreateGUI(QWidget* parent)
  443. {
  444. BlendSpaceMotionContainerWidget* picker = aznew BlendSpaceMotionContainerWidget(m_blendSpaceNode, parent);
  445. connect(picker, &BlendSpaceMotionContainerWidget::MotionsChanged, this, [picker]()
  446. {
  447. AzToolsFramework::PropertyEditorGUIMessages::Bus::Broadcast(
  448. &AzToolsFramework::PropertyEditorGUIMessages::Bus::Events::RequestWrite, picker);
  449. });
  450. return picker;
  451. }
  452. void BlendSpaceMotionContainerHandler::ConsumeAttribute(BlendSpaceMotionContainerWidget* GUI, AZ::u32 attrib, AzToolsFramework::PropertyAttributeReader* attrValue, [[maybe_unused]] const char* debugName)
  453. {
  454. if (attrValue)
  455. {
  456. m_blendSpaceNode = static_cast<BlendSpaceNode*>(attrValue->GetInstance());
  457. GUI->SetBlendSpaceNode(m_blendSpaceNode);
  458. }
  459. if (attrib == AZ::Edit::Attributes::ReadOnly)
  460. {
  461. bool value;
  462. if (attrValue->Read<bool>(value))
  463. {
  464. GUI->setEnabled(!value);
  465. }
  466. }
  467. }
  468. void BlendSpaceMotionContainerHandler::WriteGUIValuesIntoProperty([[maybe_unused]] size_t index, BlendSpaceMotionContainerWidget* GUI, property_t& instance, [[maybe_unused]] AzToolsFramework::InstanceDataNode* node)
  469. {
  470. instance = GUI->GetMotions();
  471. }
  472. bool BlendSpaceMotionContainerHandler::ReadValuesIntoGUI([[maybe_unused]] size_t index, BlendSpaceMotionContainerWidget* GUI, const property_t& instance, [[maybe_unused]] AzToolsFramework::InstanceDataNode* node)
  473. {
  474. QSignalBlocker signalBlocker(GUI);
  475. GUI->SetMotions(instance);
  476. return true;
  477. }
  478. } // namespace EMotionFX
  479. #include <Source/Editor/PropertyWidgets/moc_BlendSpaceMotionContainerHandler.cpp>