diff --git a/include/Engine/Rendering/AnimationSystem.h b/include/Engine/Rendering/AnimationSystem.h index 1ea076fd..fd53022f 100644 --- a/include/Engine/Rendering/AnimationSystem.h +++ b/include/Engine/Rendering/AnimationSystem.h @@ -57,10 +57,13 @@ private: EntityWrapper RootNode = EntityWrapper::Invalid; double Duration; double CurrentTime = 0.0; + double Delay = 0.0; BlendTree::AutoBlendInfo BlendInfo; }; + std::list m_AutoBlendJobs; + std::unordered_map m_QueuedAutoBlendJobs; std::list m_BlendJobs; std::list m_QueuedBlendJobs; diff --git a/include/Engine/Rendering/AutoBlendQueue.h b/include/Engine/Rendering/AutoBlendQueue.h new file mode 100644 index 00000000..12dd249e --- /dev/null +++ b/include/Engine/Rendering/AutoBlendQueue.h @@ -0,0 +1,27 @@ +#ifndef AutoBlendQueue_h__ +#define AutoBlendQueue_h__ + +#include "../Core/ResourceManager.h" +#include "Skeleton.h" +#include "Model.h" +#include "BlendTree.h" + +class AutoBlendQueue +{ +public: + struct AutoBlendJob + { + EntityWrapper RootNode = EntityWrapper::Invalid; + double Duration; + double CurrentTime = 0.0; + double Delay = 0.0; + BlendTree::AutoBlendInfo BlendInfo; + }; + +private: + std::map m_BlendQueue; + + +}; + +#endif diff --git a/include/Engine/Rendering/BlendTree.h b/include/Engine/Rendering/BlendTree.h index 29ad3ca9..5605707a 100644 --- a/include/Engine/Rendering/BlendTree.h +++ b/include/Engine/Rendering/BlendTree.h @@ -60,9 +60,12 @@ public: { std::string NodeName; double progress; + bool Restart; + double AnimationSpeed; std::unordered_map StartWeights; }; + BlendTree(EntityWrapper ModelEntity, Skeleton* skeleton); ~BlendTree(); diff --git a/include/Engine/Rendering/EAutoAnimationBlend.h b/include/Engine/Rendering/EAutoAnimationBlend.h index b148664f..edd8e0bc 100644 --- a/include/Engine/Rendering/EAutoAnimationBlend.h +++ b/include/Engine/Rendering/EAutoAnimationBlend.h @@ -11,7 +11,12 @@ struct AutoAnimationBlend : Event { EntityWrapper RootNode = EntityWrapper::Invalid; std::string NodeName; - double Duration; + double Duration = 0.0; + double Delay = 0.0; + + + double AnimationSpeed = 1.0; + bool Restart = false; EntityWrapper AnimationEntity = EntityWrapper::Invalid; }; diff --git a/resources/Schema/Entities/AnimationTests2.xml b/resources/Schema/Entities/AnimationTests2.xml index aaa6de48..b5b46c85 100644 --- a/resources/Schema/Entities/AnimationTests2.xml +++ b/resources/Schema/Entities/AnimationTests2.xml @@ -3,7 +3,7 @@ - 0.40000000596046448 + 0.30000001192092896 3 @@ -21,7 +21,7 @@ - 0.80000001192092896 + 0 Models/Widgets/Lights/DirectionalLightWidget.mesh @@ -33,15 +33,15 @@ - + 8 - 0.20000000298023224 + 0.60000002384185791 - + @@ -49,12 +49,12 @@ - Aim + AimBlend FinalBlend 5 - Models/Characters/Defender/DefenderRed.mesh + Models/Characters/Assault/AssaultBlue.mesh @@ -66,110 +66,65 @@ Models/Weapons/Blue/AssaultWeaponBlue.mesh - - + - + - + - - 3 - - - - - - - - - - - AimRifleA - - false - true - + + AimPrimary + AimSecondary + 0 + - + + + + + AimRifleA + + false + true + + + + + + + + + AimSecWepA + + false + true + + + + + + - WeaponBlend + ReloadSwitchBlend MovementBlend - - - - ShootBlend - Reload - 0 - - - - - - - - ShootFast - ShootSlow - 1 - - - - - - - - ShootFastRifleU - - 1 - - - - - - - - - ShootRifleU - - 1 - - - - - - - - - - - ReloadSwitchU - - 1 - - - - - - - StandCrouchBlend - Jump + JumpDashBlend 0 @@ -185,100 +140,156 @@ - + - Walk - StrafeBlend - 1 + MovementBlend + Idle + 0 - + + + + RunWalkBlend + StrafeLRBlend + 0 + + + + + + + + Walk + Run + 1 + + + + + + + + WalkF + + + + + + + + + RunF + + 1 + + + + + + + + + + + Left + Right + 0 + + + + + + + + StrafeLeftF + + + + + + + + + StrafeRightF + + + + + + + + + + - CrouchWalkF - + IdleF + 1 - - - - Left - Right - 1 - - - - - - - - CrouchStrafeLeftF - - 1 - - - - - - - - - CrouchStrafeRightF - - 1 - - - - - - - - + - RunWalkBlend - StrafeBlend - 1 + MovementBlend + Idle - + - Run - Walk + Walk + StrafeLRBlend 0 - + - - RunF - - 1 - + + Left + Right + 0 + - + + + + + CrouchStrafeLeftF + + + + + + + + + CrouchStrafeRightF + + + + + + - WalkF - - 1 + CrouchWalkF @@ -286,33 +297,110 @@ - + + + + CrouchF + + 1 + + + + + + + + + + + + + Jump + DashBlend + 1 + + + + + + + + JumpF + + + + + + + + + + DashFBBlend + DashLRBlend + 0 + + + + + - Left - Right + DashForward + DashBackward 1 - + - StrafeLeftF - - 1 + DashForwardF + false - + - StrafeRightF - - 1 + DashBackwardF + + false + + + + + + + + + + + DashLeft + DashRight + 0 + + + + + + + + DashLeftF + + false + + + + + + + + + DashRightF + false @@ -324,543 +412,106 @@ - + + + + + + ReloadSwitch + WeaponActionBlend + 1 + + + + + - JumpF - + ReloadSwitchU + 1 + + + + IdleBlend + ShootBlend + 1 + + + + + + + + IdlePrimary + IdleSecondary + + + + + + + + IdleAssaultRifleU + + + + + + + + + IdleSecWepU + + + + + + + + + + + ShootPrimary + ShootSecondary + 0 + + + + + + + + ShootFastRifleU + + 1 + + + + + + + + + ShootSecWepFastU + + + + + + + + + - - - - - - - - - - - R_Arm_Weapon_Joint - - - - Models/Core/UnitCube.mesh - - true - - - - - - - - - - - - - R_Hand - - true - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - R_Arm - - true - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - R_Shoulder - - true - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - Neck - - true - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - Spine_3 - - true - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - Spine_2 - - true - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - Spine_1 - - true - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - Hip - - true - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - L_Leg_Top - - true - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - L_Leg_Bottom - - true - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - L_Foot - - true - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - L_Toe - - true - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - L_Shoulder - - true - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - L_Arm - - true - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - L_Hand - - true - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - L_Shoulder_Armor_Joint - - true - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - Chin - - true - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - Head - - true - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - Perietal - - true - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - L_Elbow - - true - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - R_Leg_Bottom - - true - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - R_Elbow - - true - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - R_Leg_Top - - true - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - R_Foot - - true - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - R_Toe - - true - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - R_Shoulder_Armor_Joint - - true - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - @@ -874,6 +525,31 @@ + + + + + 8 + 0.60000002384185791 + + + + + + + + + + + 8 + 0.80000001192092896 + + + + + + + diff --git a/resources/Schema/Entities/BlendTreeTest.xml b/resources/Schema/Entities/BlendTreeTest.xml new file mode 100644 index 00000000..3457fc5e --- /dev/null +++ b/resources/Schema/Entities/BlendTreeTest.xml @@ -0,0 +1,557 @@ + + + + + + 0.30000001192092896 + 3 + + + + + + + + + + + + + + + + + 0 + + + Models/Widgets/Lights/DirectionalLightWidget.mesh + + + + + + + + + + + + + 8 + 0.60000002384185791 + + + + + + + + + + + AimBlend + FinalBlend + + + 5 + Models/Characters/Assault/AssaultBlue.mesh + + + + + + + + R_Arm_Weapon_Joint + + + Models/Weapons/Blue/AssaultWeaponBlue.mesh + + + + + + + + + + + + + AimPrimary + AimSecondary + 0 + + + + + + + + AimRifleA + + false + true + + + + + + + + + AimSecWepA + + false + true + + + + + + + + + + + ReloadSwitchBlend + MovementBlend + + + + + + + + StandCrouchBlend + JumpDashBlend + 0 + + + + + + + + StandMovement + CrouchMovement + 0 + + + + + + + + MovementBlend + Idle + 0 + + + + + + + + RunWalkBlend + StrafeLRBlend + 0 + + + + + + + + Walk + Run + 1 + + + + + + + + WalkF + + + + + + + + + RunF + + 1 + + + + + + + + + + + Left + Right + 0 + + + + + + + + StrafeLeftF + + + + + + + + + StrafeRightF + + + + + + + + + + + + + IdleF + + 1 + + + + + + + + + + + MovementBlend + Idle + + + + + + + + Walk + StrafeLRBlend + 0 + + + + + + + + Left + Right + 0 + + + + + + + + CrouchStrafeLeftF + + + + + + + + + CrouchStrafeRightF + + + + + + + + + + + CrouchWalkF + + + + + + + + + + + CrouchF + + 1 + + + + + + + + + + + + + Jump + DashBlend + 1 + + + + + + + + JumpF + + + + + + + + + + DashFBBlend + DashLRBlend + 0 + + + + + + + + DashForward + DashBackward + 1 + + + + + + + + DashForwardF + false + + + + + + + + + DashBackwardF + + false + + + + + + + + + + + DashLeft + DashRight + 0 + + + + + + + + DashLeftF + + false + + + + + + + + + DashRightF + false + + + + + + + + + + + + + + + + + ReloadSwitch + WeaponActionBlend + 1 + + + + + + + + ReloadSwitchU + + 1 + + + + + + + + + IdleBlend + ShootBlend + 1 + + + + + + + + IdlePrimary + IdleSecondary + + + + + + + + IdleAssaultRifleU + + + + + + + + + IdleSecWepU + + + + + + + + + + + ShootPrimary + ShootSecondary + 0 + + + + + + + + ShootFastRifleU + + 1 + + + + + + + + + ShootSecWepFastU + + + + + + + + + + + + + + + + + + + Models/Core/UnitPlane.mesh + + + + + + + + + + + + 8 + 0.60000002384185791 + + + + + + + + + + + 8 + 0.80000001192092896 + + + + + + + + + + + + diff --git a/resources/Schema/Entities/ble b/resources/Schema/Entities/ble new file mode 100644 index 00000000..6518ee5b --- /dev/null +++ b/resources/Schema/Entities/ble @@ -0,0 +1,145 @@ + + + + + + 0.30000001192092896 + 3 + + + + + + + + + + + + + + + + + 0 + + + Models/Widgets/Lights/DirectionalLightWidget.mesh + + + + + + + + + + + + + 8 + 0.60000002384185791 + + + + + + + + + + + + + + + 5 + Models/Characters/Defender/DefenderBlue.mesh + + + + + + + + R_Arm_Weapon_Joint + + + Models/Weapons/Blue/AssaultWeaponBlue.mesh + + + + + + + + + + + AimPrimary + AimSecondary + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + Models/Core/UnitPlane.mesh + + + + + + + + + + + + 8 + 0.60000002384185791 + + + + + + + + + + + 8 + 0.80000001192092896 + + + + + + + + + + + + diff --git a/src/Engine/Rendering/AnimationSystem.cpp b/src/Engine/Rendering/AnimationSystem.cpp index 11a21881..4e7f15f6 100644 --- a/src/Engine/Rendering/AnimationSystem.cpp +++ b/src/Engine/Rendering/AnimationSystem.cpp @@ -92,9 +92,30 @@ void AnimationSystem::UpdateAnimations(double dt) double animationSpeed = (double)animationC["Speed"]; if (animationSpeed != 0.0) { + double nextTime = (double)animationC["Time"] + animationSpeed * dt; + //Pre animation end blend + if (m_QueuedAutoBlendJobs.find(entity) != m_QueuedAutoBlendJobs.end()) { + if (glm::sign(m_QueuedAutoBlendJobs.at(entity).Delay) < 0) { + if (!(bool)animationC["Loop"]) { + if (nextTime > animation->Duration + m_QueuedAutoBlendJobs.at(entity).Delay && glm::sign(animationSpeed) > 0) { + AnimationComplete(entity); + } else if (nextTime < 0 - m_QueuedAutoBlendJobs.at(entity).Delay && glm::sign(animationSpeed) < 0) { + AnimationComplete(entity); + } + } else { + if (nextTime > animation->Duration + m_QueuedAutoBlendJobs.at(entity).Delay && glm::sign(animationSpeed) > 0) { + AnimationComplete(entity); + } else if (nextTime < 0 - m_QueuedAutoBlendJobs.at(entity).Delay && glm::sign(animationSpeed) < 0) { + AnimationComplete(entity); + } + } + } + } + + if (!(bool)animationC["Loop"]) { if (nextTime > animation->Duration) { nextTime = animation->Duration; @@ -119,6 +140,7 @@ void AnimationSystem::UpdateAnimations(double dt) e.Entity = entity; e.Name = (std::string)animationC["AnimationName"]; m_EventBroker->Publish(e); + AnimationComplete(entity); while (nextTime > animation->Duration) { nextTime -= animation->Duration; @@ -128,13 +150,12 @@ void AnimationSystem::UpdateAnimations(double dt) e.Entity = entity; e.Name = (std::string)animationC["AnimationName"]; m_EventBroker->Publish(e); - + AnimationComplete(entity); while (nextTime < 0) { nextTime += animation->Duration; } } } - (double&)animationC["Time"] = nextTime; } } @@ -143,7 +164,7 @@ void AnimationSystem::UpdateAnimations(double dt) void AnimationSystem::UpdateWeights(double dt) { - /* for (auto it = m_BlendJobs.begin(); it != m_BlendJobs.end(); it++) { + for (auto it = m_BlendJobs.begin(); it != m_BlendJobs.end();) { if (!it->BlendEntity.Valid()) { it = m_BlendJobs.erase(it); continue; @@ -161,7 +182,9 @@ void AnimationSystem::UpdateWeights(double dt) it = m_BlendJobs.erase(it); } } - }*/ + + ++it; + } for (auto it = m_AutoBlendJobs.begin(); it != m_AutoBlendJobs.end();) { @@ -214,7 +237,7 @@ void AnimationSystem::UpdateWeights(double dt) void AnimationSystem::AnimationComplete(EntityWrapper animationEntity) { - for (auto it = m_QueuedBlendJobs.begin(); it != m_QueuedBlendJobs.end(); it++) { + for (auto it = m_QueuedBlendJobs.begin(); it != m_QueuedBlendJobs.end();) { if (!it->BlendEntity.Valid() || !it->AnimationEntity.Valid()) { it = m_QueuedBlendJobs.erase(it); continue; @@ -229,10 +252,28 @@ void AnimationSystem::AnimationComplete(EntityWrapper animationEntity) bj.CurrentTime = 0.0; m_BlendJobs.push_back(bj); it = m_QueuedBlendJobs.erase(it); + continue; } + ++it; } + + if (m_QueuedAutoBlendJobs.find(animationEntity) != m_QueuedAutoBlendJobs.end()) { + AutoBlendJob abj = m_QueuedAutoBlendJobs.at(animationEntity); + + if (!abj.RootNode.Valid() || !animationEntity.Valid()) { + m_QueuedAutoBlendJobs.erase(animationEntity); + } else { + m_AutoBlendJobs.push_back(abj); + m_QueuedAutoBlendJobs.erase(animationEntity); + } + + + + } + + } bool AnimationSystem::OnAnimationBlend(Events::AnimationBlend& e) @@ -256,17 +297,16 @@ bool AnimationSystem::OnAnimationBlend(Events::AnimationBlend& e) m_QueuedBlendJobs.push_back(qbj); return true; } + } else { + BlendJob bj; + bj.BlendEntity = e.BlendEntity; + bj.StartWeight = (double)e.BlendEntity["Blend"]["Weight"]; + bj.GoalWeight = e.GoalWeight; + bj.Duration = e.Duration; + bj.CurrentTime = 0.0; + m_BlendJobs.push_back(bj); + return true; } - - BlendJob bj; - bj.BlendEntity = e.BlendEntity; - bj.StartWeight = (double)e.BlendEntity["Blend"]["Weight"]; - bj.GoalWeight = e.GoalWeight; - bj.Duration = e.Duration; - bj.CurrentTime = 0.0; - m_BlendJobs.push_back(bj); - - return true; } @@ -280,18 +320,39 @@ bool AnimationSystem::OnAutoAnimationBlend(Events::AutoAnimationBlend& e) return false; } - AutoBlendJob abj; - abj.RootNode = e.RootNode; - abj.CurrentTime = 0.0; - abj.Duration = e.Duration; + if (e.AnimationEntity.Valid()) { + AutoBlendJob abj; + abj.RootNode = e.RootNode; + abj.CurrentTime = 0.0; + abj.Duration = e.Duration; + abj.Delay = e.Delay; - BlendTree::AutoBlendInfo abInfo; - abInfo.NodeName = e.NodeName; - abInfo.progress = 0.0; - - abj.BlendInfo = abInfo; + BlendTree::AutoBlendInfo abInfo; + abInfo.NodeName = e.NodeName; + abInfo.progress = 0.0; + abInfo.Restart = e.Restart; + abInfo.AnimationSpeed = e.AnimationSpeed; + abj.BlendInfo = abInfo; - m_AutoBlendJobs.push_back(abj); + m_QueuedAutoBlendJobs[e.AnimationEntity] = abj; + return true; + } else { + AutoBlendJob abj; + abj.RootNode = e.RootNode; + abj.CurrentTime = 0.0; + abj.Duration = e.Duration; + + BlendTree::AutoBlendInfo abInfo; + abInfo.NodeName = e.NodeName; + abInfo.progress = 0.0; + abInfo.Restart = e.Restart; + abInfo.AnimationSpeed = e.AnimationSpeed; + + abj.BlendInfo = abInfo; + + m_AutoBlendJobs.push_back(abj); + return true; + } } @@ -301,8 +362,6 @@ bool AnimationSystem::OnInputCommand(const Events::InputCommand& e) if (e.Value == 1.f) { if (e.Command == "BlendTest0") { - - auto blendComponents = m_World->GetComponents("BlendAdditive"); if (blendComponents == nullptr) { @@ -314,11 +373,12 @@ bool AnimationSystem::OnInputCommand(const Events::InputCommand& e) EntityWrapper entity = EntityWrapper(m_World, bc.EntityID); if (entity.Name() == "Assault") { - Events::AutoAnimationBlend aeb; aeb.Duration = m_BlendTime1; aeb.NodeName = m_AnimationName1; aeb.RootNode = entity; + aeb.Restart = true; + m_EventBroker->Publish(aeb); } @@ -338,15 +398,183 @@ bool AnimationSystem::OnInputCommand(const Events::InputCommand& e) if (entity.Name() == "Assault") { - Events::AutoAnimationBlend aeb; - aeb.Duration = m_BlendTime2; - aeb.NodeName = m_AnimationName2; - aeb.RootNode = entity; - m_EventBroker->Publish(aeb); + { + Events::AutoAnimationBlend aeb; + aeb.Duration = m_BlendTime2; + aeb.NodeName = m_AnimationName2; + aeb.RootNode = entity; + aeb.Restart = true; + m_EventBroker->Publish(aeb); + } + + { + Events::AutoAnimationBlend aeb; + aeb.Duration = m_BlendTime2; + aeb.NodeName = "Run"; + aeb.RootNode = entity; + aeb.Restart = true; + aeb.AnimationEntity = entity.FirstChildByName("DashLeft"); + m_EventBroker->Publish(aeb); + } } } } + + + if(e.Command == "DashForward") { + auto blendComponents = m_World->GetComponents("BlendAdditive"); + + if (blendComponents == nullptr) { + return false; + } + for (auto& bc : *blendComponents) { + EntityWrapper entity = EntityWrapper(m_World, bc.EntityID); + + if (entity.Name() == "Assault") { + { + Events::AutoAnimationBlend aeb; + aeb.Duration = 0.1; + aeb.NodeName = "DashForward"; + aeb.RootNode = entity; + aeb.Restart = true; + m_EventBroker->Publish(aeb); + } + { + Events::AutoAnimationBlend aeb; + aeb.Duration = 0.3; + aeb.NodeName = "Run"; + aeb.RootNode = entity; + aeb.Restart = true; + aeb.Delay = 0; + aeb.AnimationEntity = entity.FirstChildByName("DashForward"); + m_EventBroker->Publish(aeb); + } + } + } + + } else if (e.Command == "DashBackward") { + auto blendComponents = m_World->GetComponents("BlendAdditive"); + + if (blendComponents == nullptr) { + return false; + } + for (auto& bc : *blendComponents) { + EntityWrapper entity = EntityWrapper(m_World, bc.EntityID); + + if (entity.Name() == "Assault") { + { + Events::AutoAnimationBlend aeb; + aeb.Duration = 0.1; + aeb.NodeName = "DashBackward"; + aeb.RootNode = entity; + aeb.Restart = true; + m_EventBroker->Publish(aeb); + } + { + Events::AutoAnimationBlend aeb; + aeb.Duration = 0.3; + aeb.NodeName = "Run"; + aeb.RootNode = entity; + aeb.Restart = true; + aeb.Delay = -0.3; + aeb.AnimationEntity = entity.FirstChildByName("DashBackward"); + m_EventBroker->Publish(aeb); + } + } + } + } else if (e.Command == "DashLeft") { + auto blendComponents = m_World->GetComponents("BlendAdditive"); + + if (blendComponents == nullptr) { + return false; + } + for (auto& bc : *blendComponents) { + EntityWrapper entity = EntityWrapper(m_World, bc.EntityID); + + if (entity.Name() == "Assault") { + { + Events::AutoAnimationBlend aeb; + aeb.Duration = 0.1; + aeb.NodeName = "DashLeft"; + aeb.RootNode = entity; + aeb.Restart = true; + m_EventBroker->Publish(aeb); + } + { + Events::AutoAnimationBlend aeb; + aeb.Duration = 0.3; + aeb.NodeName = "Run"; + aeb.RootNode = entity; + aeb.Restart = true; + aeb.Delay = -0.3; + aeb.AnimationEntity = entity.FirstChildByName("DashLeft"); + m_EventBroker->Publish(aeb); + } + } + } + } else if (e.Command == "DashRight") { + auto blendComponents = m_World->GetComponents("BlendAdditive"); + + if (blendComponents == nullptr) { + return false; + } + for (auto& bc : *blendComponents) { + EntityWrapper entity = EntityWrapper(m_World, bc.EntityID); + + if (entity.Name() == "Assault") { + { + Events::AutoAnimationBlend aeb; + aeb.Duration = 0.1; + aeb.NodeName = "DashRight"; + aeb.RootNode = entity; + aeb.Restart = true; + m_EventBroker->Publish(aeb); + } + { + Events::AutoAnimationBlend aeb; + aeb.Duration = 0.3; + aeb.NodeName = "Run"; + aeb.RootNode = entity; + aeb.Restart = true; + aeb.AnimationEntity = entity.FirstChildByName("DashRight"); + aeb.Delay = -0.3; + m_EventBroker->Publish(aeb); + } + } + } + } else if (e.Command == "Jump") { + auto blendComponents = m_World->GetComponents("BlendAdditive"); + + if (blendComponents == nullptr) { + return false; + } + for (auto& bc : *blendComponents) { + EntityWrapper entity = EntityWrapper(m_World, bc.EntityID); + + if (entity.Name() == "Assault") { + { + Events::AutoAnimationBlend aeb; + aeb.Duration = 0.35; + aeb.NodeName = "Jump"; + aeb.RootNode = entity; + aeb.Restart = true; + m_EventBroker->Publish(aeb); + } + { + Events::AutoAnimationBlend aeb; + aeb.Duration = 0.35; + aeb.NodeName = "Run"; + aeb.RootNode = entity; + aeb.Restart = false; + aeb.AnimationEntity = entity.FirstChildByName("Jump"); + m_EventBroker->Publish(aeb); + } + } + } + } + + } } diff --git a/src/Engine/Rendering/AutoBlendQueue.cpp b/src/Engine/Rendering/AutoBlendQueue.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/Engine/Rendering/BlendTree.cpp b/src/Engine/Rendering/BlendTree.cpp index 8b044134..f7381d4d 100644 --- a/src/Engine/Rendering/BlendTree.cpp +++ b/src/Engine/Rendering/BlendTree.cpp @@ -207,6 +207,21 @@ BlendTree::AutoBlendInfo BlendTree::AutoBlendStep(AutoBlendInfo blendInfo) { std::vector goalNodes = FindNodesByName(blendInfo.NodeName); + if (blendInfo.Restart) { + for (auto it = goalNodes.begin(); it != goalNodes.end(); it++) { + EntityWrapper entity = (*it)->Entity; + + if (entity.Valid()) { + if (entity.HasComponent("Animation")) { + (double&)entity["Animation"]["Time"] = 0.0; + (double&)entity["Animation"]["Speed"] = blendInfo.AnimationSpeed; + } + } + } + blendInfo.Restart = false; + } + + if(goalNodes.size() == 0) { return blendInfo; } else if(goalNodes.size() == 1) {