Can you change the speed of a Montage mid playthrough?

Hi forum!

I asked this question already on AnswerHub, but I thought I’d get it out to as many people as possible to see if there was anyone who could help me with this.

The AH question is here: Dynamically altering inPlayRate of AnimMontage? - Character & Animation - Unreal Engine Forums

Basically, I want to play a Montage from AniMontage that has its In Play Rate altered as time goes on; I want the Montage to pick up speed the longer it’s been played (up to a cap). Is there a way this can be done?

Thanks,
Shrooblord

I am not very familiar with the UE4 yet as I’ve been using it for a month but I was trying something the other day and found the “Montage Set Play Rate” node. Just tried it quickly and it seems to work for changing the play rate during the montage is going. It appears only in the AnimationBP if you have Context Sensitive turned on.

Did this BP quickly to test it:

And it worked for me (I’ve got a few seconds long jump montage the jump-in animation start off with a slow-mo jumping then mid air it’s at normal speed and the landing is again slow).
However I’m not sure if this will work the way you want it with (with a Timeline?)

Thanks. I didn’t know this node existed.

I’ve fooled around with it a bit, but it appears Timelines are not supported in the AnimBlueprints. I will try to see if I can get it to work somehow using this node anyway.

Sorry for double posting - I should’ve just tried this in the first place and then post.

So I did the following:

But this causes a crash with the cause being an infinite loop. Why? As far as I can tell, it first checks whether or not AnimPlay Rate (APR) is lower than 2.5. It is, for its initial setting is 1.0. Then, after 0.5 seconds, it sets APR to 1.2 by filling in the equation (1.2^x) with x being X Value (initially 1). Then it sets the new play rate for the montage to 1.2, and then adds 0.5 to X Value.
Then the next While iteration fires. It checks APR. It’s now 1.2 It waits 0.5 seconds due to the delay, then sets APR to 1.31, since x in the exponent is now 1.5. It sets the new play rate for the montage and increases X Value once more, to 2 this time.

Eventually, at X Value = 5.5, APR=1.2^5.5=2.73 exceeds 2.5, the condition the While Loop is checking for. This is where the loop aborts.

Except the program seems to think it’s hit an infinite loop. How come?

I’m not sure if this will be practical or if it will work at all but maybe you could have a loop which is like this
-Start the montage with the speed you want
-Enter the loop (which breaks when the montage is no longer supposed to run)
-Set Play Rate (using a float variable)
-Increase the float if hasn’t reached a certain amount (the cap for the speed)
-Repeat the loop

I don’t know if you will need to put delay somewhere (maybe before/after the Set Play Rate) but that’s my idea. Actually I’m not even sure if you can make loops in the animationBP or if UE won’t crash with infinite loop since it did the last time I tried to make a similar loop.

Edit: oh well seems like you tried it already and it crashed for infinite loop like I suspected. I’m kind of interested in why this crashes myself as I was making some loops last week and they ended up being infinite even when they clearly had an end.

I’ve programmed in some other languages before and I know clearly the dangers of an infinite while loop. But getting it here, in an instance where only six iterations of the loop SHOULD bring about its termination waaaaaay before any ‘oh no, this thing is infinite’-catch should occur, surprises me greatly.

I hope it’s not a general Blueprint bug and I’m just making myself feel like I’m an idiot for missing something for nothing. :stuck_out_tongue:

In Blueprints, Loops attempt to iterate themselves entirely within a single frame. Putting a delay node inside a loop is a no-no because it means the loop will be unable to complete within a single frame.

Performing repeating actions is best handled with looping Timers, not code loops.

I’m not sure what you’re trying to do, but if you’re trying to make an accelerating animation, might I suggest notifies?

For example, if you have a looping animation, you can put a Notify at the start of it which executes your code check to increase speed. Every time the anim loops it will slowly accelerate.

You could also use a curve within the montage to control the play rate, for instance.

Interesting. I hadn’t thought of Notifies actually executing code. I’d only seen them as… well, notifications FOR code to keep track of where in an animation the montage was. I’ll check that possibility out some time.

For now, I’ve approached it like so:


Simple and does the trick!

===

But that leaves me with a question about while loops. I’m used to While loops being used in the way where I perform some code, yield the system and keep executing code until some statement is no longer true:


while z < 3 do
print("This is the "..z.."th time this message has appeared!");
z += 1;
end

sense, where you’d want to iterate a line of code a number of times while a certain statement remains true.

If in Blueprint you’re not supposed to use the While loop in this over-time iterative manner, then why does BP even have While loops? What are they used for?

A while loop is used to perform some iterated task while a condition is true.

Like for example, suppose you wanted a spawn point to spawn enough actors such that there are always X in a hallway. If you have a variable for the number of actors currently in the hallway (which is decreasing as they die or leave the area, and which is increasing whenever a new one is spawned) you can go “While ActorCount < 10, SpawnActorFromClass (enemy)”.

The loop will spawn actors and increase the count until there are 10… With the net effect of if there are 4 actors in the hallway, 6 will spawn. If you throw a grenade and 2 die in an explosion, 2 will spawn. Etc.

Basically it’s just another syntax approach to the same loop effect of “performing a task (n) times based on some not-constant value of (n), and executing it as a single thing”, which is how UE uses loops.

I almost never use loops outside of Construction Scripts (for building things based on not-constant parameters, like instancing meshes) and Area-Of-Effect events (I must do this to all actors overlapped by this sphere, however many that is). Looping behaviors get handled by Timelines or Timers exclusively.