ScriptedEntityTweenerSystemComponent.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0 OR MIT
  5. *
  6. */
  7. #include <AzCore/RTTI/BehaviorContext.h>
  8. #include <AzCore/Serialization/SerializeContext.h>
  9. #include <AzCore/Serialization/EditContext.h>
  10. #include <ScriptedEntityTweener/ScriptedEntityTweenerBus.h>
  11. #include <ScriptedEntityTweener/ScriptedEntityTweenerEnums.h>
  12. #include "ScriptedEntityTweenerSystemComponent.h"
  13. namespace ScriptedEntityTweener
  14. {
  15. ////////////////////////////////////////////////////////////////////////////////////////////////////
  16. //! ScriptedEntityTweenerNotificationBusHandler Behavior context handler class
  17. class ScriptedEntityTweenerNotificationBusHandler :
  18. public ScriptedEntityTweenerNotificationsBus::Handler,
  19. public AZ::BehaviorEBusHandler
  20. {
  21. public:
  22. AZ_EBUS_BEHAVIOR_BINDER(ScriptedEntityTweenerNotificationBusHandler, "{118D3961-17C7-46E9-B9AC-61682D57E8D3}", AZ::SystemAllocator,
  23. OnComplete, OnUpdate, OnLoop, RemoveCallback, OnTimelineAnimationStart);
  24. void OnComplete(int callbackId) override
  25. {
  26. Call(FN_OnComplete, callbackId);
  27. }
  28. void OnUpdate(int callbackId, const AZStd::any& currentVal, float progressPercent) override
  29. {
  30. Call(FN_OnUpdate, callbackId, currentVal, progressPercent);
  31. }
  32. void OnLoop(int callbackId) override
  33. {
  34. Call(FN_OnLoop, callbackId);
  35. }
  36. void RemoveCallback(int callbackId) override
  37. {
  38. Call(FN_RemoveCallback, callbackId);
  39. }
  40. void OnTimelineAnimationStart(int timelineId, const AZ::Uuid& uuid, const AZStd::string& componentName, const AZStd::string& propertyName)
  41. {
  42. Call(FN_OnTimelineAnimationStart, timelineId, uuid, componentName, propertyName);
  43. }
  44. };
  45. void ScriptedEntityTweenerSystemComponent::Reflect(AZ::ReflectContext* context)
  46. {
  47. if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
  48. {
  49. serialize->Class<ScriptedEntityTweenerSystemComponent, AZ::Component>()
  50. ->Version(0)
  51. ;
  52. }
  53. AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context);
  54. if (behaviorContext)
  55. {
  56. behaviorContext->EBus<ScriptedEntityTweenerBus>("ScriptedEntityTweenerBus")
  57. ->Event("AnimateEntity", &ScriptedEntityTweenerBus::Events::AnimateEntityScript)
  58. ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::List)
  59. ->Event("SetOptionalParams", &ScriptedEntityTweenerBus::Events::SetOptionalParams)
  60. ->Event("Stop", &ScriptedEntityTweenerBus::Events::Stop)
  61. ->Event("Pause", &ScriptedEntityTweenerBus::Events::Pause)
  62. ->Event("Resume", &ScriptedEntityTweenerBus::Events::Resume)
  63. ->Event("SetPlayDirectionReversed", &ScriptedEntityTweenerBus::Events::SetPlayDirectionReversed)
  64. ->Event("SetSpeed", &ScriptedEntityTweenerBus::Events::SetSpeed)
  65. ->Event("SetInitialValue", &ScriptedEntityTweenerBus::Events::SetInitialValue)
  66. ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::List)
  67. ->Event("GetVirtualPropertyValue", &ScriptedEntityTweenerBus::Events::GetVirtualPropertyValue);
  68. behaviorContext->EBus<ScriptedEntityTweenerNotificationsBus>("ScriptedEntityTweenerNotificationBus")
  69. ->Handler<ScriptedEntityTweenerNotificationBusHandler>();
  70. behaviorContext->Enum<(int)ScriptedEntityTweener::EasingMethod::Linear>("ScriptedEntityTweenerEasingMethod_Linear")
  71. ->Enum<(int)ScriptedEntityTweener::EasingMethod::Quad>("ScriptedEntityTweenerEasingMethod_Quad")
  72. ->Enum<(int)ScriptedEntityTweener::EasingMethod::Cubic>("ScriptedEntityTweenerEasingMethod_Cubic")
  73. ->Enum<(int)ScriptedEntityTweener::EasingMethod::Quart>("ScriptedEntityTweenerEasingMethod_Quart")
  74. ->Enum<(int)ScriptedEntityTweener::EasingMethod::Quint>("ScriptedEntityTweenerEasingMethod_Quint")
  75. ->Enum<(int)ScriptedEntityTweener::EasingMethod::Sine>("ScriptedEntityTweenerEasingMethod_Sine")
  76. ->Enum<(int)ScriptedEntityTweener::EasingMethod::Expo>("ScriptedEntityTweenerEasingMethod_Expo")
  77. ->Enum<(int)ScriptedEntityTweener::EasingMethod::Circ>("ScriptedEntityTweenerEasingMethod_Circ")
  78. ->Enum<(int)ScriptedEntityTweener::EasingMethod::Elastic>("ScriptedEntityTweenerEasingMethod_Elastic")
  79. ->Enum<(int)ScriptedEntityTweener::EasingMethod::Back>("ScriptedEntityTweenerEasingMethod_Back")
  80. ->Enum<(int)ScriptedEntityTweener::EasingMethod::Bounce>("ScriptedEntityTweenerEasingMethod_Bounce")
  81. ->Enum<(int)ScriptedEntityTweener::EasingType::In>("ScriptedEntityTweenerEasingType_In")
  82. ->Enum<(int)ScriptedEntityTweener::EasingType::Out>("ScriptedEntityTweenerEasingType_Out")
  83. ->Enum<(int)ScriptedEntityTweener::EasingType::InOut>("ScriptedEntityTweenerEasingType_InOut");
  84. }
  85. }
  86. void ScriptedEntityTweenerSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
  87. {
  88. provided.push_back(AZ_CRC("ScriptedEntityTweenerService"));
  89. }
  90. void ScriptedEntityTweenerSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
  91. {
  92. incompatible.push_back(AZ_CRC("ScriptedEntityTweenerService"));
  93. }
  94. void ScriptedEntityTweenerSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
  95. {
  96. (void)required;
  97. }
  98. void ScriptedEntityTweenerSystemComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
  99. {
  100. (void)dependent;
  101. }
  102. void ScriptedEntityTweenerSystemComponent::Init()
  103. {
  104. }
  105. void ScriptedEntityTweenerSystemComponent::Activate()
  106. {
  107. ScriptedEntityTweenerBus::Handler::BusConnect();
  108. AZ::TickBus::Handler::BusConnect();
  109. }
  110. void ScriptedEntityTweenerSystemComponent::Deactivate()
  111. {
  112. ScriptedEntityTweenerBus::Handler::BusDisconnect();
  113. AZ::TickBus::Handler::BusDisconnect();
  114. }
  115. void ScriptedEntityTweenerSystemComponent::AnimateEntity(const AZ::EntityId& entityId, const AnimationParameters& params)
  116. {
  117. auto animationTask = m_animationTasks.find(ScriptedEntityTweenerTask(entityId));
  118. if (animationTask == m_animationTasks.end())
  119. {
  120. animationTask = m_animationTasks.insert(ScriptedEntityTweenerTask(entityId)).first;
  121. }
  122. animationTask->AddAnimation(params);
  123. }
  124. void ScriptedEntityTweenerSystemComponent::SetOptionalParams(float timeIntoAnimation, float duration, int easingMethod, int easingType, float delayTime, int timesToPlay, bool isFrom, bool isPlayingBackward, const AZ::Uuid& animationId, int timelineId, int onCompleteCallbackId, int onUpdateCallbackId, int onLoopCallbackId)
  125. {
  126. AnimationParameters& params = m_tempParams;
  127. params.m_animationProperties.m_easeMethod = static_cast<EasingMethod>(easingMethod);
  128. params.m_animationProperties.m_easeType = static_cast<EasingType>(easingType);
  129. params.m_animationProperties.m_timeIntoAnimation = timeIntoAnimation;
  130. params.m_animationProperties.m_timeDuration = duration;
  131. params.m_animationProperties.m_timeToDelayAnim = delayTime;
  132. params.m_animationProperties.m_timesToPlay = timesToPlay;
  133. params.m_animationProperties.m_isFrom = isFrom;
  134. params.m_animationProperties.m_isPlayingBackward = isPlayingBackward;
  135. params.m_animationProperties.m_animationId = animationId;
  136. params.m_animationProperties.m_timelineId = timelineId;
  137. params.m_animationProperties.m_onCompleteCallbackId = onCompleteCallbackId;
  138. params.m_animationProperties.m_onUpdateCallbackId = onUpdateCallbackId;
  139. params.m_animationProperties.m_onLoopCallbackId = onLoopCallbackId;
  140. }
  141. void ScriptedEntityTweenerSystemComponent::AnimateEntityScript(const AZ::EntityId& entityId, const AZStd::string& componentName, const AZStd::string& virtualPropertyName, const AZStd::any& paramTarget)
  142. {
  143. AnimationParameters& params = m_tempParams;
  144. AnimationParameterAddressData data(componentName, virtualPropertyName);
  145. params.m_animationParameters.emplace(data, paramTarget);
  146. AnimateEntity(entityId, params);
  147. m_tempParams.Reset();
  148. }
  149. void ScriptedEntityTweenerSystemComponent::Stop(int timelineId, const AZ::EntityId& entityId)
  150. {
  151. auto animationTask = m_animationTasks.find(ScriptedEntityTweenerTask(entityId));
  152. if (animationTask == m_animationTasks.end())
  153. {
  154. return;
  155. }
  156. animationTask->Stop(timelineId);
  157. }
  158. void ScriptedEntityTweenerSystemComponent::Pause(int timelineId, const AZ::EntityId& entityId, const AZStd::string& componentName, const AZStd::string& virtualPropertyName)
  159. {
  160. auto animationTask = m_animationTasks.find(ScriptedEntityTweenerTask(entityId));
  161. if (animationTask == m_animationTasks.end())
  162. {
  163. return;
  164. }
  165. AnimationParameterAddressData data(componentName, virtualPropertyName);
  166. animationTask->SetPaused(data, timelineId, true);
  167. }
  168. void ScriptedEntityTweenerSystemComponent::Resume(int timelineId, const AZ::EntityId& entityId, const AZStd::string& componentName, const AZStd::string& virtualPropertyName)
  169. {
  170. auto animationTask = m_animationTasks.find(ScriptedEntityTweenerTask(entityId));
  171. if (animationTask == m_animationTasks.end())
  172. {
  173. return;
  174. }
  175. AnimationParameterAddressData data(componentName, virtualPropertyName);
  176. animationTask->SetPaused(data, timelineId, false);
  177. }
  178. void ScriptedEntityTweenerSystemComponent::SetPlayDirectionReversed(int timelineId, const AZ::EntityId& entityId, const AZStd::string& componentName, const AZStd::string& virtualPropertyName, bool rewind)
  179. {
  180. auto animationTask = m_animationTasks.find(ScriptedEntityTweenerTask(entityId));
  181. if (animationTask == m_animationTasks.end())
  182. {
  183. return;
  184. }
  185. AnimationParameterAddressData data(componentName, virtualPropertyName);
  186. animationTask->SetPlayDirectionReversed(data, timelineId, rewind);
  187. }
  188. void ScriptedEntityTweenerSystemComponent::SetSpeed(int timelineId, const AZ::EntityId& entityId, const AZStd::string& componentName, const AZStd::string& virtualPropertyName, float speed)
  189. {
  190. auto animationTask = m_animationTasks.find(ScriptedEntityTweenerTask(entityId));
  191. if (animationTask == m_animationTasks.end())
  192. {
  193. return;
  194. }
  195. AnimationParameterAddressData data(componentName, virtualPropertyName);
  196. animationTask->SetSpeed(data, timelineId, speed);
  197. }
  198. void ScriptedEntityTweenerSystemComponent::SetInitialValue(const AZ::Uuid& animationId, const AZ::EntityId& entityId, const AZStd::string& componentName, const AZStd::string& virtualPropertyName, const AZStd::any& initialValue)
  199. {
  200. auto animationTask = m_animationTasks.find(ScriptedEntityTweenerTask(entityId));
  201. if (animationTask == m_animationTasks.end())
  202. {
  203. return;
  204. }
  205. AnimationParameterAddressData data(componentName, virtualPropertyName);
  206. animationTask->SetInitialValue(data, animationId, initialValue);
  207. }
  208. AZStd::any ScriptedEntityTweenerSystemComponent::GetVirtualPropertyValue(const AZ::EntityId& entityId, const AZStd::string& componentName, const AZStd::string& virtualPropertyName)
  209. {
  210. AZStd::any toReturn;
  211. AnimationParameterAddressData data(componentName, virtualPropertyName);
  212. auto animationTask = m_animationTasks.find(ScriptedEntityTweenerTask(entityId));
  213. if (animationTask != m_animationTasks.end())
  214. {
  215. animationTask->GetVirtualPropertyValue(toReturn, data);
  216. }
  217. else
  218. {
  219. ScriptedEntityTweenerTask task(entityId);
  220. task.GetVirtualPropertyValue(toReturn, data);
  221. }
  222. return toReturn;
  223. }
  224. void ScriptedEntityTweenerSystemComponent::Reset()
  225. {
  226. m_animationTasks.clear();
  227. }
  228. void ScriptedEntityTweenerSystemComponent::OnTick(float deltaTime, AZ::ScriptTimePoint /*time*/)
  229. {
  230. for (auto& animTask : m_animationTasks)
  231. {
  232. animTask.Update(deltaTime);
  233. }
  234. //TODO: Possible optimization: Logic to remove "stale" animation tasks, use a "garbage collection" method to defer set removal operations (which is O(n))
  235. for (auto it = m_animationTasks.begin(); it != m_animationTasks.end(); )
  236. {
  237. if (!((*it).GetIsActive()))
  238. {
  239. it = m_animationTasks.erase(it);
  240. }
  241. else
  242. {
  243. ++it;
  244. }
  245. }
  246. }
  247. int ScriptedEntityTweenerSystemComponent::GetTickOrder()
  248. {
  249. return AZ::TICK_LAST;
  250. }
  251. }