Skip to content

GGgRain/Unreal-Volt

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

43 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Volt

The Slate Architecture Animation System for Unreal Engine

Badge showing the total of project forks Badge showing the total of project stars Badge showing project license type Chat on Discord Release Notes

About   |   Main Features   |   Installation   |   Quickstart   |   Usecases   |   Supports

🔍 About

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!

📋 Main Features

1. Intuitive Declarative Animation

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

2. Simple, Thus Powerful Usages

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.

3. Light-Weighted Performance & Multithreading Support

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.

📥 Installation

We assume that you are going to use Volt on your plugin.

  1. Download and unzip the plugin.
  2. Copy-paste the contents in the Source folder to your plugin.
  3. 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.
  4. 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.

Modules

  • 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.

🏁 Quickstart

Declaring Animation & Modules

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 with UVolt_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 with UVolt_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

Playing Animation

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.

Learning Further...

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.

Storing Animation Track

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);

Stopping Animation

You can use VOLT_STOP_ANIM( AnimationTrack ) to stop specific animation from a specific animation manager with its track.

VOLT_STOP_ANIM( Track );

Checking Animation State

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...
}

Finding Volt Interface For Slate

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!

Making Independent Animation Manager

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 )...

Releasing Animation Manager Explicitly

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);

Making New Animation Modules

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.

📷 Usecases

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!

📢 Supports

If you have any questions related to Volt, please visit our official discord

📝 License

This project is licensed under the MIT License. For more details, please refer to the LICENSE file.