Good day, fellas. So I was working on an animation and I wanted it to be paused at the last frame when the key is being held down and play another animation [the release] animation when the key is released.
I did, (Just a replica of what I made, since the original one can be complex.
1 | UIService.InputBegan:connect( function (inputKey) |
2 | if inputKey.KeyCode = = Enum.KeyCode.Q then |
3 | anim = humanoid:LoadAnimation(folder [ "Animation" ] ) |
4 | wait( 1 ) |
5 | anim:AdjustSpeed( 0 ) |
6 | end |
7 | end |
I tried doing this but later realized that it's probably not a very efficient way of doing it, since I'll be doing it on several animations as well, with different time length (I was thinking the wait(1)
would be changed everytime and it also feels un-optimized to me having the wait. So, detecting whether the animation is at its last keyframe, how should I do that? What event of the animation can get the length of the animation I'm playing?
I am using the Moon Animator 2 for Animating it. So, I really hope it doesn't interfere that much on this problem. What do you recommend? (Not asking for a script, rather a recommendation of a solution to this)
There are some ways of checking the last keyframe. First you should try
1 | AnimationTrack.Stopped:Connect( function ) |
but sometimes it actually waits the animation stops and do the function after it, making it perform kindda ugly; so you can use AnimationEvents, creating an event in the last keyframe before the end of your anim, and to listen to it you use
1 | AnimationTrack:GetMarkerReachedSignal( function ) |
Or in last case maybe you could try AnimationTrack.Changed event, like
1 | AnimationTrack.Changed:Connect( function (property) |
2 | if property = TimePosition and AnimationTrack.TimePosition = = time.Length* 0.9 then |
3 | -- do ur stuff |
4 | end |
5 | end ) |
but I don't know if this last one will work.
Links to help working with animation events:
https://developer.roblox.com/en-us/articles/using-animation-editor
https://developer.roblox.com/en-us/api-reference/function/AnimationTrack/GetMarkerReachedSignal
In last case, you can use the deprecated form of animation events, that were the keyframe reached event, try serching about it.
Maybe you will have to face a new problem while trying those out, that is the memory leak caused by connecting an event inside another event. Instead of doing this:
1 | UserInputService.InputBegan:Connect( function () |
2 | if keycode = = x then |
3 | AnimationTrack:GetMarkerReachedSignal( function ) |
4 | -- if you pressed the input 10 times, you created 10 connections, so it will listen to the event 10 times and more as much you press. When it is 1k the game will start to freeze. |
5 | end |
6 | end ) |
Do this
01 | local holding = false |
02 |
03 | UserInputService.InputBegan:Connect( function () |
04 | if keycode = = x then |
05 | holding = true |
06 | end |
07 | end ) |
08 |
09 | UserInputService.InputEnded:Connect( function () |
10 | if keycode = = x then |
11 | holding = false |
12 | end |
13 | end ) |
14 |
15 | AnimationTrack:GetMarkerReachedSignal( function () |
16 | if holding = = true then |
17 | -- do ur stuff |
18 | end |
19 | end ) |
Else, to make an animation freeze in a certain point (after calling the events) you can set the AnimationTrack.TimePosition to any number and stop the animation through AnimationTrack:AdjustSpeed(0)