Visulie ─ A Novel, All-Purpose Animation, Data, and Effects Suite

Models are kind of finicky because of how Roblox implements them. There really isn’t a location property on models, so your only option to move the model is to set the WorldPivot.

However, if you don’t use PrimaryPart, it should work as expected. This is because if a PrimaryPart is set, the WorldPivot is automatically set, which may or may not break your animation. For this reason, I might remove PrimaryPart from the animatable properties. Is there a reason you’re using PrimaryPart in your animation?

Ah, unfortunately, that is a bug that you can’t do anything about. If you have an old save file, you can probably get your progress back that way. Fortunately, it should not happen again once you update the plugin.

Again, I’m so sorry that this happened! I know how jarring it is to lose progress. I went through extensive testing to try to catch critical bugs. But alas, I’m just one developer and can’t catch everything. I’m very grateful that you’re going out of your way to report these to me!


Visulie 1.1.8

Bug Fixes

1 Like

Take a gander, the answer will shock you. (hint: jobs)

if you care enough, im pretty sure there are free alternatives

1 Like

thx again :3
No worries, since I’m still a beginner any experience I gather is critically important and making another animation will just help improve my skills :slight_smile:

No worries, I’m not going out of my way to report bugs I’m opening more ways by reporting them :slight_smile: (corny ahh line right here)

1 Like

Few suggestions and some quality of life that this plugin needs:

  • Copy & Paste Keyframes

  • Attributes to be Animatable (Not sure if this is supported already just adding it here)

  • Support animatable Instances of the new Audio API so it can be played through Studio not in runtime only

  • Animatable of Adding / Removing Tags on instances. So functionality can be extended through other systems using CollectionService

  • Able to visualize all keyframes of all the instances. So we can easily align keyframe timing rather than switching back and forth.

  • Undo/Redo (If this is implemented already then mine is bugged)

  • Use Plugin Studio Window rather than implementing the UI straight into the viewport so right-click context can work. and being able to dock the editor.

  • Renaming Instances inside the Rig Folder (For some reason this does not work for me)

All in all great plugin! would recommend to other artists looking into animating effects without coding at all. and can be easily integrated to other workflows.

1 Like

Thanks for the suggestions!

Planned! But, it may take a while.

Although not totally out of the question, I’m unsure whether these are necessarily useful for the nature of the plugin. If you have specific use-cases for this, I would be happy to reconsider!

This is not a bad idea, actually. I may implement it on a property-by-property basis (so you can view all the keyframes of “x” property at once). If I simply display everything, it will get cluttered quite quickly.

This is planned! I’ll add support for the new Audio API very soon.

I’ve been wanting to add this feature for quite a long time. However, I’ve never gotten around to doing it due to its complexity. It’s such a simple feature at a high level, but it’s grudgingly difficult to implement. I do, however, have a separate, simpler idea of not undoing, but rather “save states” where you can load up previous states if you want to “undo” something.

Once the studio design refresh is fully out, I will likely switch to a docked version. I want to make this plugin blend in with the existing UI that studio has, but the final design is largely unconfirmed at this time.

This should be fixed once I release the next update!

1 Like

Visulie V1.2.9

Bug Fixes

Features

  • Audio API is now supported. There are exceptions! Some properties, such as “AngleAttenuation”, are restricted to the Roblox engine, and thus cannot be animated.
  • “Interactable” property of GuiObjects is now supported

Audio Api

Unlike traditional sound instances, you can actually hear the audio play in studio! Take note that you will have to set up your own audio listeners and outputs to hear the audio, as shown in the video under the “Camera” instance.

3 Likes

Wow very fast turn around! glad you implemented some of the suggestions especially the new Audio API! Since on my current project I don’t use the old Sound I can finally change it real quick! for all the effects I made.

Since the effects rig are being reconstructed I can’t add any external functionality without coupling the effect to other systems by fetching the instances at creation using GetRigDependencies().

The only way to decouple the functionality is to use CollectionService to fetch any spawned effects with the tag and do some functionality. Attributes work hand in hand with the CollectionService as-well.

Here’s an ideas I came up on the fly (probably very specific scenario):
Assuming Attributes and Tags are animatable

I have an effect that spawns a firefly that emits light on and off. The firefly has a Tag of FireflyEffect the tag is applied at creation on frame 0 and a Boolean Attribute called IsLightOn and starts at false.
I animate the firefly to make it neon when the light is on, I also animate the Attribute to be true and vise-versa.

Lets say we have a mechanic in the game where we point the direction to where the closest firefly is when the light is on.

I can easily make a separate system de-coupled from the effect itself and the effect has nothing to do or need to know about this mechanic and its only sole job is to just animate it.

I can then use CollectionService to see the closest firefly from the character that currently spawn and check if their attribute IsLightOn is true.

I can easily extend this functionality to even more complex to where we add LightPower Attribute on the firefly and animate the lightPower from 0 - 100 and add tweening styles as-well.

and a system could probably get this LightPower Attribute to compare between fireflies to which who are brighter overtime and so on.

and maybe at the end of the animation we remove the FireflyEffect Tag because it was about to fade out or something so it does not get included when fetching the closest firefly.

Hopefully you get the gist of it! there are many more use cases doing this way and it makes architecting the game easier.

2 Likes

Got a bug to where the TargetInstance or SourceInstance is nil probably because it does not exist yet on initialize. its from the Wires when playing at run-time.

image

Edit: Forgot to update the renderer! nevermind my bad.

1 Like

Hmmm. I can push out an update to the renderer to obtain instances from the animation directly. GetRigDependencies() was created to get, well… the rig dependencies (all the items of the rig). For your use case, I guess I could add a method to fetch a specific instance with something like GetInstance(instanceName) to obtain the instance, which should improve your current workflow.

As for the actual feature request, your use case is pretty appealing! I’m assuming, from your description, that you’re playing an animation on the rig, but also using tags and attributes to add dynamic elements to both the animation and to assist in external behavior. Quite a genius idea if you ask me.

I’ll try to add this as soon as I can. But it may take a while.

Haha, I was starting to get confused why it doesn’t work because I couldn’t reproduce the issue :sweat_smile:.

I guess I’ll try to make it more clear about when the renderer should be updated. Right now, it’s safe to assume that you should update the renderer every single time an update comes out.

However, assuming that most users don’t end up editing the source code, I can add an extra check every time the plugin is loaded, which should suffice for most circumstances.

3 Likes

Ts me again.

Remember my animation priority that you (rightfully) turned down?
You said there’d be no point since the animations override each other. Turns out thats not the case :confused:


In this video you can clearly see how only the last part of the “overriding animation” is being played
I also tried ending the other animation with

renderer.getActiveAnimation(...):Destroy(false)

but that didn’t really work. Neither did pausing the animation or waiting until it is done

My recommendation: Add a :Stop() method (cus pause is just pausing it or sum idk)

1 Like

There is no :Stop() method. :Pause() exists.

You can override animations by using loadAnimation() on the rig you’re currently playing.

local Animation = Visulie.new(data)
Animation:Play()

task.wait(0.5)

local rigDepenencies = Animation:GetRigDependencies()
local OverrideAnimation = Visulie.loadAnimation(otherData, someCFrame, rigDependencies)
OverrideAnimation:Play()

I’ve never run into issues with overriding animations. Are you able to provide the code you’re using? I’m not sure what’s wrong from looking at the video, either.


this would be my code. Sorry for making an unclear video

Animation I (the spin)

Animation II (the uhh… bigger spin)

The result of running the code (AnimationId = 1) on the looping spin-animation results in the video above

1 Like

Thanks for the extra information! I believe I have found the underlying issue. This should be fixed now after updating the plugin and replace the Visulie Renderer. Again, Thanks for bringing this up! Let me know if there are still any issues.


Visulie V1.2.10

1 Like

i do got a few suggestions

  • randomized values on certain properties

  • custom formula support for example if we would want to use math.cos or something else

  • step?, i don’t know how i could call this but, a background animation that blends with the others (maybe this already exists), like a spinning animation but it still plays when you try to change the cframe by , up , down or any direction

  • support for camera animations, as far as i know, moon animator has a way to export camera animations, so if visulie had his own exporting method for camera, or just atleast to preview them would be nice

Also i’ve got a question, is there any way to apply force/Impulse to a part in the animator?

Thank you again.

Also I’ve got three more suggestions coming right up:

Animation editor

  • Support for un-animatable objects
    > This is really needed. Instead of deleting the objects, keep them without adding any keyframes. Helps with model hierarchies alot.
    > Example: You want to animate a Tool. Because of the deletion of the tool ancestor, you will only be left with the Handle, which can be animated.

    Now I get this isn't necessary but it would make animating some things easier. I'd much rather call loadanimation on Tool than on Tool.Handle

  • Ancestor name variety.
    Each animated object usually has a common ancestor for all parts. Renaming this makes the animation un-usable. This sucks in a way. I don't know how and if its "fix"-able but it sure would be nice.
    > Example: I made some coins the player can collect in my game. I wanted their names to be numerated (1,2,3...) but since the animation would only work on one (called "1"), all of my coins are now called "1"

Animation playback

  • Now I would assume this is a really, REALLY advanced feature but if you add it you would probably make this plugin stand out even further from all of the others from the competition.
    Keyframe variables
    Let me explain. When animating humanoids, I ran into an issue. I can animate their movement (limbs), but not the location they move to. (or i just suck :sob: ) This is where this suggestion could come in. The animation module is designed in such a way that the Keyframe's values can be changed, allowing for advanced movement / adaptability. This is technically already possible with your current saveable animation-modules but realistically it is too hard (to understand) for an average code editor dweller like me. Let me create a code example of what this could looke like:

    local animation = require(path.Animation)
    -- You would be able to connect variables to keyframes (the variable would be a reference to a keyfame)
    animation.KeyFrameVariables.VariableNameHere.Value = game:GetService("Players").LocalPlayer.Character:GetPivot()
    Visuliue.loadAnimation(animation, Enemy.CFrame, {Enemy})
    -- This would move the "enemy" to the "localplayer" whilst also animating the limbs (for example with a run animation)
    

This was a feature I wanted to implement for a long time as well. I was thinking some sort of “property” system where you can adjust a property, and the keyframes will adjust accordingly. However, after tinkering with the code for a while, I decided that this was much too complex and unperformant.

This is not out of the question, though. It is, however, unknown at this time whether this will ever be implemented.

Yes, you can do this by playing the animation and calling :SetOrigin() on the animation to place it somewhere else.

You can technically animate the camera, but you’re going to have to separate the camera animation from the rigged animation (so you create one animation for the camera, a separate animation for the effects, then play them both at the same time). Visulie isn’t meant to be a cutscene plugin. It is meant to create independent animations.

Not yet. Is there a use case for this? Usually, parts are anchored in animations. But I guess this could be useful for unanchored physical assemblies.

There is a similar planned feature that will be released in the future. Although it doesn’t specifically fit your use case, it can help in some instances.

I play a lot of animations on existing rigs, here’s a crude example:

As you can see, the only things that are animated are the model and particles. All the parts in between don’t really matter.

My thoughts on the implementation is to have an option to “ignore” certain instances. Once you ignore an instance, all of its descendants are ignored as well. These instances will also not be exported. Let me know if you have any issues with this behavior!

This is a tricky one. I initially wanted to be able to animate anything regardless of name. This can be achievable, but it does add a level of complexity. I may do this in the future, but it’s not guaranteed.

1 Like

Yeah, that’s it, it would be great to make physics based animations for parts, i’ve seen it before and they look cool, for example a bouncing part that then resizes or his transparency disappears

Visulie V2.3.11

Bug fixes

  • Importing rigs where parts are parented to models are no longer bugged in world space, and now are correctly stored in object space.
  • Methods on the final frame now fire correctly instead of being ignored.

Adjustments

  • Removed destroyOnCompletion parameter for :Play() and :Resume().

Features

  • Added new method to the Visulie renderer, PlayThenDestroy(), which plays the animation once (regardless of looping state), then destroys the animation.

Visulie now supports animation and playback of attributes and tags!

Simply add/remove tags/attributes, and it will be recorded. Here’s an example of a use-case!

Demonstration:


This is a new comprehensive Visulie version! Please update your data!

2 Likes

Hi, I was reading your module and I found it quite interesting, but some doubts arose…

  1. Is it useful for non-static Objects, vehicles or similar?

  2. At production level, how optimized is it? Let’s say a big map with many animatable instances?

  3. How does it work, does it have some form of Client to Client Replication, can it be run only on client and manage not to load non-visible animations?

While possible, it’s not meant to simulate physics objects (for now, at least).

The module is quite optimized at what it does. It’s up to you to ensure that you’re playing animations effectively across a map (for example, pausing animations that cannot be seen). If you have, say, 10000 animations running, it will lag regardless.

It’s purely client-sided (but you can also play it serverside, but there is no custom replication). If you want animations to replicate, you must design a replication system yourself (which is standard for custom scripted animations).

Again, it’s up to you to decide how to play/not play animations depending on visibility.

2 Likes