diff --git a/Content/Documentation/ScriptingAPI-Documentation.md b/Content/Documentation/ScriptingAPI-Documentation.md index f05bd7a07..44ad1f1c4 100644 --- a/Content/Documentation/ScriptingAPI-Documentation.md +++ b/Content/Documentation/ScriptingAPI-Documentation.md @@ -1677,6 +1677,7 @@ Note that CharacterComponent is NOT using physics, but a custom character logic. - Jump(float amount) -- Jump upwards by an amount. The jump will be executed in the next scene update, with collisions. - Turn(Vector value) -- Turn towards a direction continuously. - Lean(float value) -- Lean sideways, negative values mean left, positive values mean right +- Shake(float horizontal, opt float vertical = 0, opt float frequency = 100, opt float decay = 10) -- Apply shaking to the character. horizontal, vertical: movement amount in directions; frequency: speed of movement; decay: speed of slowing down - AddAnimation(Entity entity) -- Adds animation for tracking blending state. The simple animation blending will perform blend-out for each animation except the currenttly active one - PlayAnimation(Entity entity) -- Play the animation. This will be blended in as primary animation, others will be belnded out. diff --git a/WickedEngine/wiScene.cpp b/WickedEngine/wiScene.cpp index 0d761662a..e694a6e79 100644 --- a/WickedEngine/wiScene.cpp +++ b/WickedEngine/wiScene.cpp @@ -5868,11 +5868,27 @@ namespace wi::scene XMVECTOR offset = XMLoadFloat3(&character.relative_offset); offset = XMVector3TransformNormal(offset, facing_rot); + + const float shake_timer_decay = std::exp(-character.shake_decay * character.shake_timer); + const float shake_intesity_horizontal = character.shake_horizontal * shake_timer_decay; + const float shake_intesity_vertical = character.shake_vertical * shake_timer_decay; + if (shake_intesity_horizontal > 0.001f || shake_intesity_vertical > 0.001f) + { + offset += XMVectorSet( + shake_intesity_horizontal * std::sin(character.shake_frequency * character.shake_timer), + shake_intesity_vertical * std::sin(character.shake_frequency * -character.shake_timer), + shake_intesity_horizontal * std::cos(character.shake_frequency * character.shake_timer), + 0 + ); + } + transform->Translate(offset); transform->SetDirty(); } + character.shake_timer += dt; + }); wi::jobsystem::Wait(ctx); } diff --git a/WickedEngine/wiScene_BindLua.cpp b/WickedEngine/wiScene_BindLua.cpp index 1a5a6b668..d498b0261 100644 --- a/WickedEngine/wiScene_BindLua.cpp +++ b/WickedEngine/wiScene_BindLua.cpp @@ -8212,6 +8212,7 @@ Luna::FunctionType CharacterComponent_BindLua::metho lunamethod(CharacterComponent_BindLua, Jump), lunamethod(CharacterComponent_BindLua, Turn), lunamethod(CharacterComponent_BindLua, Lean), + lunamethod(CharacterComponent_BindLua, Shake), lunamethod(CharacterComponent_BindLua, AddAnimation), lunamethod(CharacterComponent_BindLua, PlayAnimation), @@ -8345,6 +8346,33 @@ int CharacterComponent_BindLua::Lean(lua_State* L) component->Lean(wi::lua::SGetFloat(L, 1)); return 0; } +int CharacterComponent_BindLua::Shake(lua_State* L) +{ + int argc = wi::lua::SGetArgCount(L); + if (argc < 1) + { + wi::lua::SError(L, "Shake(float horizontal, opt float vertical = 0) not enough arguments!"); + return 0; + } + float horizontal = wi::lua::SGetFloat(L, 1); + float vertical = 0; + float frequency = 100; + float decay = 10; + if (argc > 1) + { + vertical = wi::lua::SGetFloat(L, 2); + if (argc > 2) + { + frequency = wi::lua::SGetFloat(L, 3); + if (argc > 3) + { + decay = wi::lua::SGetFloat(L, 4); + } + } + } + component->Shake(horizontal, vertical, frequency, decay); + return 0; +} int CharacterComponent_BindLua::AddAnimation(lua_State* L) { diff --git a/WickedEngine/wiScene_BindLua.h b/WickedEngine/wiScene_BindLua.h index 9bb53c340..20a81608e 100644 --- a/WickedEngine/wiScene_BindLua.h +++ b/WickedEngine/wiScene_BindLua.h @@ -2002,6 +2002,7 @@ namespace wi::lua::scene int Jump(lua_State* L); int Turn(lua_State* L); int Lean(lua_State* L); + int Shake(lua_State* L); int AddAnimation(lua_State* L); int PlayAnimation(lua_State* L); diff --git a/WickedEngine/wiScene_Components.cpp b/WickedEngine/wiScene_Components.cpp index 1210f5212..026156283 100644 --- a/WickedEngine/wiScene_Components.cpp +++ b/WickedEngine/wiScene_Components.cpp @@ -2792,6 +2792,14 @@ namespace wi::scene { leaning_next = amount; } + void CharacterComponent::Shake(float horizontal, float vertical, float frequency, float decay) + { + shake_horizontal = horizontal; + shake_vertical = vertical; + shake_frequency = frequency; + shake_decay = decay; + shake_timer = 0; + } void CharacterComponent::AddAnimation(Entity entity) { animations.push_back(entity); diff --git a/WickedEngine/wiScene_Components.h b/WickedEngine/wiScene_Components.h index d21b67c89..da0f49e8f 100644 --- a/WickedEngine/wiScene_Components.h +++ b/WickedEngine/wiScene_Components.h @@ -2492,6 +2492,11 @@ namespace wi::scene }; std::shared_ptr pathfinding_thread; // separate allocation, mustn't be reallocated while path finding thread is running const wi::VoxelGrid* voxelgrid = nullptr; + float shake_horizontal = 0; + float shake_vertical = 0; + float shake_frequency = 0; + float shake_decay = 0; + float shake_timer = 0; // Apply movement to the character in the next update void Move(const XMFLOAT3& direction); @@ -2503,6 +2508,11 @@ namespace wi::scene void Turn(const XMFLOAT3& direction); // Lean sideways, negative values mean left, positive values mean right void Lean(float amount); + // Apply shaking to the character + // horizontal, vertical: movement amount in directions + // frequency: speed of movement + // decay: speed of slowing down + void Shake(float horizontal, float vertical = 0, float frequency = 100, float decay = 10); void AddAnimation(wi::ecs::Entity entity); void PlayAnimation(wi::ecs::Entity entity); diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 14d8c5bb2..0e11ec5e1 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wi::version // minor features, major updates, breaking compatibility changes const int minor = 71; // minor bug fixes, alterations, refactors, updates - const int revision = 812; + const int revision = 813; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);