About | Main Features | Installation | Quickstart | Usecases | Supports
Volt_Showcase_1.mp4
Volt_Showcase_2.mp4
Volt is a modular animation system for Unreal Slate Architecture powered by various UObject-based modules that can manipulate slate properties as you want in both runtime and editor, allowing you to declare animations very quickly, intuitively, and easily with unique declarative animation syntax.
Volt lets you make detailed slate animations that are well-structured and lightweight in performance - while keeping development(animating) very intuitive, easy, and fast.
This project was part of Joint Project, a powerful full-modular conversation scripting framework, especially Volt took place in the editor module to animate the slates on the editor without limitation on the production and performances.
The project's distribution intends to enable you to use it on your editor for the visual part. Let's make Unreal's editor beautiful!
Please consider leaving a star if you loved this project! ⭐
Volt allows users to animate slates with unique and intuitive animation declaration syntax. This helps you quickly test out and build any animation production with slates.
Declarative_Animation.mp4
Animating slates with Volt is remarkably easy - You might think it's illegal to do this easily!
You don't need to do any modification to the existing slate types to make it work with Volt - It will work with any slate types as they are.
If you want to animate SBorder instance? Just put that in VOLT_PLAY_ANIMATION()
then it will magically create all the necessary objects internally - You don't need to care about them. All you have to know is how to declare animations and use each module to make animations as you want.
// Make SBorder slate here.
ChildSlot[
SAssignNew(Border, SBorder)
.BorderBackgroundColor(OutlineNormalColor)
[
...
]
];
// Declare a volt animation
UVoltAnimation* Anim = VOLT_MAKE_ANIMATION()
(
VOLT_MAKE_MODULE(UVolt_ASM_InterpBackgroundColor)
.TargetColor(OutlinePressColor)
);
// Play the animation with that SBorder slate. It's just like this.
VOLT_PLAY_ANIM(Border, BorderColorAnim);
Considering the main reason why there are not so many plugins or systems with animated UI mostly comes from the complexity of the vanilla Unreal Engine's Slate animation development process (It's horribly slow and difficult to achieve), The level of simplexity of the usage of Volt will let you make much more detailed and creative visual productions.
Volt has been designed to be fast and lighted-weighted on the performance and memory aspect
It tries to reduce the amount of memory usage, total object counts and iteration counts internally with a ton of performance-related optimization logic - including unique garbage-collecting logic that works with the ownership system, selective variables implementation...
Plus, Volt never makes bottleneck on the game thread, because it works with multithreading - many of the intensive actions are all done in an independent thread. This lets users focus solely on the animation development while not caring too much about the performance issue.
Also, many features including querying slate instances or animation tracks are designed to be fast enough ( O(1) ) to support maximum performance - thus Volt could be practical enough for every project.
We assume that you are going to use Volt on your plugin.
- Download and unzip the plugin.
- Copy-paste the contents in the Source folder to your plugin.
- Go to your plugin's .uplugin file and add the modules there. (Volt, VoltCore, VoltEditor). Please check out the Volt.uplugin to see the module type and loading phase for each module.
- And MOST IMPORTANTLY, rename all the classes and module names to something unique, to prevent compatibility issues with other programs that use Volt too. Unfortunately, Epic Games forbid us to make the plugin dependent on the plugin on the marketplace so we can not share libraries between multiple projects unless it becomes a part of the engine itself.
- Volt - The module that contains some basic ready-to-use modules and variables for the plugin.
- VoltCore - The module that contains the fundamental classes for the framework.
- VoltEditor - The module that contains editor-only classes, including VoltStarship (Showcase + Boilerplate)
Note
If you are working on the actual project, we recommend excluding the VoltEditor module in the final build.
Now it's time to make an actual animation instance. You can use VOLT_MAKE_ANIMATION( AnimationClassName )
macro to declare a new animation with the provided type animation (typically UVoltAnimation
) and VOLT_MAKE_MODULE( ModuleClassName )
macro to create a module for the provided module class.
You can wrap modules with ( )
to feed the modules to the animation, then the animation will get those modules and use them to animate the slate.
Tip
() operator
(wrapping modules with ( )
) also works for the modules that can have submodules on providing submodules for them.
In Volt 1.1, we have 3 object types that take submodules, UVoltAnimation
, UVolt_ASM_Sequence
, UVolt_ASM_Simultaneous
.
In this example, You can see that UVoltAnimation
object will be created with UVolt_ASM_Sequence
inside, which has 2 submodules (UVolt_ASM_InterpWidgetTransform
) that will animate the slate's render transform as provided.
You can also see that this animation will work like this: changing a slate's render transform to make it move and forth (UVolt_ASM_InterpWidgetTransform
, first one will animate the slate's X location like -50 -> 50, second one will animate it 50 -> -50 ) continuously. (UVolt_ASM_Sequence
, loop has been enabled by .bShouldLoop(true)
)
UVoltAnimation* Animation = VOLT_MAKE_ANIMATION() (
VOLT_MAKE_MODULE(UVolt_ASM_Sequence)
.bShouldLoop(true)
(
VOLT_MAKE_MODULE(UVolt_ASM_InterpWidgetTransform)
.bUseStartWidgetTransform(true)
.StartWidgetTransform(FWidgetTransform(FVector2D(-50, 0), FVector2D(1, 1), FVector2D(0, 0), 0))
.TargetWidgetTransform(FWidgetTransform(FVector2D(50, 0), FVector2D(1, 1), FVector2D(0, 0), 0))
.RateBasedInterpSpeed(3),
VOLT_MAKE_MODULE(UVolt_ASM_InterpWidgetTransform)
.bUseStartWidgetTransform(true)
.StartWidgetTransform(FWidgetTransform(FVector2D(50, 0), FVector2D(1, 1), FVector2D(0, 0), 0))
.TargetWidgetTransform(FWidgetTransform(FVector2D(-50, 0), FVector2D(1, 1), FVector2D(0, 0), 0))
.RateBasedInterpSpeed(3),
)
)
Note
In Volt 1.1, We officially supports 11 modules for the system:
General Modules; Can be used to control the playback of the animation or other modules:
UVolt_ASM_Sequence
: a module that plays the submodules sequentially (One-By-One) while waiting the previous module to be ended.UVolt_ASM_Simultaneous
: a module that plays the submodules Simultaneously (All-At-Once). It's designed to be used withUVolt_ASM_Sequence
since animation's module playback is simultaneous by default.UVolt_ASM_Delay
: a module that will be active for the specified duration. This is useful to use withUVolt_ASM_Sequence
to create delayed animation.
Interpolation Related Modules; Interpolate specific variables of the target slate. they all supports various interpolation modes for your more dynamic animation production.
Interpolation_Modules.mp4
UVolt_ASM_InterpBackgroundColor
UVolt_ASM_InterpBoxProperties
: (SBox specific)UVolt_ASM_InterpChildSlotPadding
UVolt_ASM_InterpColor
UVolt_ASM_InterpForegroundColor
UVolt_ASM_InterpRenderOpacity
UVolt_ASM_InterpWidgetTransform
Only the final process is left! Let's play the animation we made. Let's use VOLT_PLAY_ANIM(SlateToAnimate, Animation )
macro to animate the slate.
VOLT_PLAY_ANIM(SharedThis(this), Animation);
Then you will see something like this.
Volt provides all the other features for making & managing slates in an organized manner.
Important
In this document, we will cover how to use specific macros that are most useful in general usage only. If you need any further help, Please join the official discord!
Or you can find out some release notes to learn about the features - whenever we have anything to explain about them, we leave very detailed explanations for the changes and features.
You can store FVoltAnimationTrack
from VOLT_PLAY_ANIM( ... )
macro that indicates the track of the animation playing in the animation manager. You can use this track to manage (query, check playback state, stop) the playing animation.
FVoltAnimationTrack& Track = VOLT_PLAY_ANIM( SharedThis(this), Animation);
You can use VOLT_STOP_ANIM( AnimationTrack )
to stop specific animation from a specific animation manager with its track.
VOLT_STOP_ANIM( Track );
You can use VOLT_CHECK_PLAYING_ANIM( AnimationTrack )
to check whether a specific animation is still being played or finished.
if (VOLT_CHECK_PLAYING_ANIM( Track )) {
// logic when animation is still being played...
}
You can find the corresponding IVoltInterface
for a specific slate with VOLT_FIND_OR_ASSIGN_INTERFACE_FOR( SlateWeakPtr )
macro.
Querying uses a hash table internally - guaranteed to provide O(1) time efficiency (at good condition) - you can spam it as you want. Don't be shy!
For native slate types, It will return UVoltProxy
object that wraps the provided slate as a return.
Tip
Volt internally uses IVoltInterface
as the unit of the object that can be animated with Volt system, which must provide UVoltVariableCollection
instance that contains all the animated variables that are used to animate the slate, and also the TargetSlate that the interface will animate.
But for most cases, Slates aren't directly inherited from IVoltInterface
, so we wrap the slate with a proxy object called UVoltProxy
that inherits IVoltInterface
instead of that slate.
This is why it returns UVoltProxy
instead, and this is why the system can take any type of slate with no difficulty. It's not a black magic!
Volt system uses UVoltAnimationManager
to animate slates internally so you needed to make one for your slates, but from Volt 1.2, now UVoltSubsystem
supports Shared Animation Manager
that lets you never care about implementing animation managers explicitly.
But sometimes, especially when you have to use VOLT_STOP_ALL_ANIM()
frequently, you might want to implement UVoltAnimationManager
that will animate only specific widgets you got.
Note
One UVoltAnimationManager
can animate multiple slates as you want, So it's up to you whether to make UVoltAnimationManager
per each slate or reuse any external, already existing instance to save memory usage.
On such cases, you can make a UVoltAnimationManager
instance with macro: VOLT_IMPLEMENT_MANAGER( AnimationManagerPropertyAddress, OwnerSlateSharedPtr )
or VOLT_IMPLEMENT_MANAGER( AnimationManagerPropertyAddress, OwnerUObject )
// In SVoltSampleStarshipTab.h...
UVoltAnimationManager* AnimationManager = nullptr;
// In SVoltSampleStarshipTab.cpp...
VOLT_IMPLEMENT_MANAGER(&AnimationManager, SharedThis(this));
You can use your animation manager by specifying optional parameter of the functions by providing it as the first parameter; VOLT_PLAY_ANIM( AnimationManagerPtr, SlateToAnimate, Animation )
VOLT_STOP_ANIM( AnimationManagerPtr, Track )
...
You can use VOLT_RELEASE_MANAGER( AnimationManagerPtrAddress )
to explicitly release the target UVoltAnimationManager
instance.
Note
UVoltAnimationManager
instances will be automatically GC'd by the system after some time even if you don't explicitly release it. You can check out UVoltSubsystem.cpp to learn more about clean-up code if you want.
We also wrote clear instructions related to the GC logic in the UVoltSubsystem.h. You can check them out as well.
VOLT_RELEASE_MANAGER(&AnimationManager);
Sometimes, default-provided modules aren't sufficient for you to create your desired production. But you can always make new modules for your needs!
However, this topic will be too long for this document. Please visit this release note for further details.
Joint, and Joint Native is using this plugin to animated their editor slates. Please let us know if you want to share your great project with Volt!
If you have any questions related to Volt, please visit our official discord
This project is licensed under the MIT License. For more details, please refer to the LICENSE file.