Timeline
@Acid Bubbles No, I have some experience in scripting, so I have no problem in writing my own plugin driving the animations. The problem is the limited access we have from a third party plugin. But after digging through your code i have found a solution for the pose snapping problem: I have to call "Stop", then set the desired animation via the registered JSONStorableStringChooser called "Animation", followed by a "Play" call :)

But I'm a bit curious why i can't get the current value from the StringChooser. GetStringChooserParamValue("Animation") always yieds an empty string. Same if i do GetStringChooserJSONParam("Animation").val. Does it get reset to "" directly after setting it (without callback of course)?
But i can set it, and thats what i primarily need. I can keep track of the currently playing animation myself.

Now there is only the problem with the switch from "Play All" to just "Play".
 
The Animation drop down is only there for backward compatibility... it's a "set only" value. There were talks of adding an API on Timeline for more complex cases but there were always simpler workarounds.

For the Play All, technically Play is just while you make the animation. You can however make sure animations are not shared on layers and have a "noop" animation on each layer to achieve a similar result.
 
@Acid Bubbles Ok, then please don't remove it in future updates. My plugin relies heavily on it.
One thing i would find very useful: An option to sync renaming on other atoms (same name rule). Right now i have to repeat renaming on all other atoms to not break synchronization. Or is that feature already available and i missed it?
 
I don't plan on making big breaking changes at this point, it would be suicide ;) There's a sync feature but it's not super reliable, and renaming has to be done manually. I didn't make it automatic because you would have no way to "unlink" animations, and I didn't add a dedicated button, so... yeah, planning helps in that case.
 
Ok, i understand that it's not a priority for you. It's not strictly necessary if you plan ahead.
But it would be useful to me. And if there was a toggle for the auto rename feature (options), then one would only have to toggle it off temporarily to unlink.
Or otherwise: I would keep that feature off by default, and if the user decides to rename a bunch of linked anims, he can toggle it on.
 
Last edited:
I still can't find how to import animation to the current segment rather than create a new segment. Or something like moving one animation from one segment to another segment, can somebody tell me how to do that?

Thanks!
 
@Wxy_332 You should go to the create segment screen, then press "convert anim to segment". This creates a new segment containing the current anim. I would also like a feature to move an anim to another segment, but that doesn't seem to be possible. Probably because there could be a target mismatch between the two segments. The algorithm would have to check which targets are missing and add them automatically.

If you really need it, you can try editing the scene.json directly. But don't forget to make a backup first ;)
 
@Acid Bubbles Forget about the renaming thing. It's not that important. I can still edit the .json by search and replace.
But there are 3 things i really, really would like to be implemented because I'm stuck with my project and can't do what i have in mind:
1. A way to retrieve the currently playing animation as a JSONStorableString I can get the value of.
2. A way to toggle between "play" and "play all" via script, i.e. prevent auto sequencing.
3. This probably requires a bit more work, but I miss a feature to exclude all animations from randomized sequencing whose names contain a specific string.
I'm assuming the randomizer iterates trough the list of all anims and selects the ones containing the specified group identifier, i.e. "anims/". Maybe you could add a text input field so one could set an additional string that should be excluded from the said list. like ">".

Background for 3:
I have poses with different animations that should be called randomly, i.e. A/00, A/01, B/00, B/01. And there are transitions between the poses, like A/>B and B/>A, which should also have the possibility to get selected randomly, hence the group identifiers. I want the transition A/>B beeing sequenced by B/* to have variety. But then the problem is, that A/>B can be directly followed by B/>A, leading to an unnatural in and out behaviour. So, I'd like to set the sequencing of A/>B to B/*, but exclude all transitions (containing ">").

If you don't have the time for this, I'm tempted to add this to your code myself. Would you grant me permission to provide the modified version with my scene? I could also send you the files for inspection. If it's all right you could make an official minor update of it, too.
Could you please point me to the file containing the definition of the animation dropdown and the play buttons in the UI? This should be all i need for investigating further (for 1 and 2). I simply could not find them, there are so many files :O

Thanks!
 
Last edited:
@Wxy_332 You can only import animations if they are compatible with a segment, meaning they have the exact same list of animatables targets. Otherwise you can import in a new temporary segment, and then copy and paste the keyframes (in More, Bulk) that you want.
 
@CheesyFX I was asked a few times for a "current animation storable", I think I have found a good way to do it. Can't say when I'll have time, but at least I have a solution. But please don't wait on me, I just don't have enough arms to do everything I have to do.

Preventing sequencing would be extremely tricky, so that will not happen, even if there are good reasons for it.

As for "anything but", this is also tricky in terms of UI...

If you want to contribute, I greatly encourage you to do so, I hoped for help for a long time but not many people are ready to invest the time :) You can checkout the code here: https://github.com/acidbubbles/vam-timeline and provide pull requests, I can try and point you in the right direction. However I don't want custom Timeline versions around, even though I do understand it'd make things easier for you, it'll be hell for me as people will start referencing custom versions without being aware of it, and contacting me about issues I will not be able to understand because I won't have the right information. So please, don't do that.

- This is the sequence drop down: https://github.com/acidbubbles/vam-timeline/blob/master/src/UI/Screens/SequencingScreen.cs#L96
- This is where the scheduling happens: https://github.com/acidbubbles/vam-...s/Animations/AtomAnimation.Sequencing.cs#L149

The project is fairly complex, so don't expect a quick fix, but if you're ready to iterate a few times to get it right, I'll be happy to support you!
 
@Acid Bubbles Thanks, I'll definitely try to contribute. If i have something in mind i want to make it possible, no mather the costs :)

"current animation storable"
Yeah, you already have a member called "current". Why not simply ask for it's name attribute (assuming the anim has one)? But I could not grasp what it points to if there's currently a blend happening. Also, I'm not sure yet what I want the getter to output in that case...

Preventing sequencing would be extremely tricky
Hmm, i thought i'd just register an Action executing the callback of the "play" button, maybe preceeded by a "stop" call. Because that does what i need. But maybe thats to naive, i have to get a better insight of the project. But wait: Is the problem tied to the fact that the stop and play callbacks act on the animation selected in the UI and not the one currently playing? Then maybe we have to select the currently playing anim first (by setting the Animation JSON). Seems i have to look into setting up a getter for the current anim first (if you're not fast enough ;)).

As for "anything but", this is also tricky in terms of UI...
Again, hmmm. I don't get why the UI is the problem. I'd just set up a 1 line text input field below the "Play Next" chooser. You already have to scroll in that screen, so there is no beautiful arrangement getting "destroyed" by that.

I totally understand that you don't want to mess with custom versions. I won't release/package anything without your approval.

The next weeks will be a bit stressful for me, but I'll come back to you when I have a question or something to show. Thanks for your help, and of course your awesome plugin :)
 
Last edited:
If you want to try doing the "getter", you should publish a storable string chooser for every segment and layer, for which the value would be updated (in AtomPlugin.cs). There should be similar code for updating speed storables you could look at.
 
Hey! I'm slowly digging deeper into your code, but there are some questions arising. What is the best way to communicate to you? Do you read your private messages? Or are you on discord? If so, am I allowed to add you there?

I want the names of the getters to be prefixed by their segment name, like "seg1.layer1" to make them unique, regardless if 2 segments hold layers of the same name. This once more made me think about why the heck are clip names not internally unique? Is there a deeper reason for it? If the user does not set up unique names across all segments and all layers, it is impossible to trigger (or change the speed of) a specific animation. Because the list 'animationNames' will contain duplicates, so that only the last registered action of that name is available.
Why didn't you set up a displayName (the one shown and editable in the UI) and an internal name, which is prefixed by <segmentName>.<layerName>. For the registered actions this name could then be used to make it unique (although the names could be very long).
Specifically for my usecase this caused a lot of headaches, because I want to be able to trigger almost any anim from my external plugin, so i had to manually add a .<segmentIdentifier> to each relevant anim to make them unique.
I could possibly make this change, but 1. it would break all scenes which depend on the action names to trigger and 2. it would be hard for me to track down each and every dependency of the names.
Either way, I try to make this new feature independent of the naming scheme.

Second question: What is the best way to document my changes, so that you can inspect them? I'm working with Rider and I don't have much experience with Git, aside from browsing and downloading some code here and there.
 
Last edited:
I just don't get your object structure. So far i have a method CreateAndRegisterLayerStorables, which should take a segment (or its id, or its name) and register the getters for each layer it contains. But I'm missing a connection between the segmentName and the segment itself, or its index.
animation.index.segmentIds seems to hold some arbitrary numbers that do not correspond to the index the segments name has in animation.index.segmentNames. After init (reload) animation.index.segmentIds only has one entry '11', altough there is only one segment. So, if i pass this id to my method, i can't get the name of the segment, because segmentNames[id] yields an 'index out of range' error. And if i pass the name of the segment, I can't find a way to get the corresponding IndexedSegment to iterate over its layers, because there is only a Dict mapping the segments by their id.
Why doesn't the IndexedSegment class contain a member holding its name? Could i add one, or is there anything I'm not aware of?

Again, I want my method to not blindly iterate over all layers in the scene, I want it to also have access to the name of the segment the layers belong to, to add a prefix to the storables names (to make them unique).
 
Last edited:
@CheesyFX You can reach out on Discord, I have my own Discord (link in all of my plugins), feel free to ping me there. It's often easier to have quick discussions there. And.... yeah, Timeline is _complex_ but also started as a cool proof of concept. I tried to keep refactoring it, but I'm not keeping up lol. Still, there's a logic despite it being far from perfect. Ask away and I'll point out the way things are built, you don't have to figure it out yourself :D

- Unique: There's qualifiedAnimationName, qualifiedLayerName, etc. which are namespace (unique across all animations). There's also an index (animation.index) to quickly access them without having to do string comparisons.
- The idea of sharing animation names across layers is to have cross-layer animations, so the goal is to have them in sync, at least as much as possible. So updating the speed of Anim 1 will update it for all layers.
- Git: I strongly suggest you learn the basics of making PRs in GitHub, this way I can easily contribute, provide feedback, etc. It was created for this purpose, so it's worth learning, and GitHub really has great tutorials to help you with it.
- By the way, you can make "ugly proof of concepts" first, so we can play with the ideas, before trying to make it clean. If the idea is clear, I can also help by writing some of the code for you, or at least pieces of it to help you navigate my mess.
- About the IDs, yeah strings are expensive, so I'm computing a int representation of names so I can look them up efficiently (yeah Timeline's complicated in part because it is very performance-oriented). That makes things harder to follow. Normally you _always_ receive a string, and find it in maps using it's ID, but you should never have to find a name from an ID, if you do you can load the animation from the map.

The way I'd do it, is when an animation is created, removed or rename (there's an event for that), rebuild a list of all layers to create a storable for it, and when an animation starts, find the matching storable from a map (using the ID, not the name, for perf) and update it's value.

Feel free to continue the conversation here, on GitHub or on Discord ;)
 
I'm wondering about the possibility of animating CycleForce parameters within the timeline. I've got all the targets configured, but only the torque seems to work. That is, affecting the rotation of the CycleForce target works, but affecting the position doesn't. I've got the timeline plugin on the person atom that I'm animating. Is there some way to get that working? It'd be awesome to be able to control the Force Factor without even leaving the main timeline.
 
It seems similar to something I noticed a while ago as well. The same thing happens with other plugins like Silver Kiss. I was activating those with trigger keyframes in the timeline. With the CycleForce I was manipulating the float params by adding them as targets. In both cases, timeline just doesn't seem to allow anything else to affect the position changes of its parent atom's controllers while it is playing an animation. Setting them while the animation is stopped affects the atom as normal, but as soon as it starts playing, position changes stop. Not a huge or unexpected issue, especially with such a good plugin. Anything that can be animated with a CycleForce or other plugin can just be hand-animated in Timeline anyway. Was just wondering if I was missing anything that would make life easier. Thanks for the response!

Edit: i played around a bit and noticed a thing. The values DO seem to update over timeline animation. The sliders animate as you'd expect, and when I check the CycleForce, it matches what it says on the timeline. But, if I hit the play button or scrub the timeline, movement stops, even though I can see in the CycleForce display that the Force Factor is high. Interestingly, in that "frozen" state, the red line on the CycleForce indicator is moving normally, but the Green and Blue line don't. I'm not sure what that indicates, but I think I'll dig around some more.

Edit Edit: Aha! I figured out the issue with the CycleForce at least. I had maxForce also set as a target param and it defaults to 0. Unsurprisingly, if your maxForce is set to 0, it doesn't matter if you change the forceFactor. Setting maxForce to 10000 at frame 1 solves the issue.
 
Last edited:
How do you save an animation with the scene when you save the scene? I am unable to get my test animation to load with my test scene.

The only way I can save the animation is by exporting it, then reloading the .json into the atom's Timeline plugin in the scene. This seems very wrong...
 
Last edited:
@Acid Bubbles how to play next segment ? i do have play segment 1 and 2 and 3 and so on but when i use that action trigger, the button 'next animation' does not play the next animation of the segment selected

as in when i go to play segment 2 it did play the animation, but i cannot play the next animation, i suspect due to the issue that when the action button ' play segment 2 ' is played, the screen still stays on segment 1, i hope it makes sense, hope you can help me on this one, also this plugin is actually really good and complex and versatile once you get used to it, but this issue i currently have is annoying :(
 
I think a video could be useful @sevenseason, normally if you have a button in VaM that triggers a segment, it should switch. It won't update the currently displayed animation though, but if you go to the Animations tab you should see that it plays. If not, the video should help me understand better.
 
I think a video could be useful @sevenseason, normally if you have a button in VaM that triggers a segment, it should switch. It won't update the currently displayed animation though, but if you go to the Animations tab you should see that it plays. If not, the video should help me understand better.

@Acid Bubbles

hope this helps, maybe i have faulty version of timeline? but i download it here so i doubt its my timeline version, (2.80)

 

Attachments

  • 2023-05-17_18-33-33.mp4
    24.7 MB
Aaaah yeah.... the Animations and Next / Previous Animation storables are... problematic. They are old things I cannot make obsolete without breaking scenes that actually navigates the UI animations. You can instead try Next Animation in Layer (or something like that) instead... Thanks, the video was helpful!
 
Aaaah yeah.... the Animations and Next / Previous Animation storables are... problematic. They are old things I cannot make obsolete without breaking scenes that actually navigates the UI animations. You can instead try Next Animation in Layer (or something like that) instead... Thanks, the video was helpful!
dang so is there really no fix for that? : /
 
Back
Top Bottom