Have you noticed that Maximo action animations (and many others) seem to have been recorded on clueless low-energy actors ?
The character seems to punch, kick a ghost or some studio air… doesn’t look good.
Just speeding up the animation ? No , that doesn’t work. The speed is higher but constant.
BUT, by putting variations in the speed of the same animation, you can transform the pace and still keep the length of the animation.
The green line is the constant speed of your animation. The blue and orange are both slopes with different curvature and lag. The yellow one is a weighted mix of the 2 curves (75% goes to the orange, 25% to the blue) …
What does the yellow curve represents : it represents an animation that roughly plays in a smooth shape the 10 first frames at same speed than a constant … but … then holds a pause during ±10 frames in which the animation seems still … then then around frame 20, runs quickly exhaust the end of the animation (± 30 frames) in the time span of 20 frames.
→ So, to mark a pause in your animation around the frame 10 , you need to weight the blue one 25% (coz 25% of 40 = 10)
So typically, this is what u want for your “kick” or “punch” animations … you want the impact lasts for some time to emphasize the impact.
What to use ?
You can use the Logistic function
L = Length of your animation (in our example : 40 )
K = The shape of your Slope ( blue:1 , orange:0.5 )
T = x0 = The midpoint of the curve (blue : 5 , orange 25)
F = x = the time (expressed as the frame)
Y = f(x) = The position in the animations
Python code
L = 40 ; F = player['frame_time'] ### F is typically the time
T1 = 5 ; T2 = 25 ; K1 = 1 ; K2 = 0.5
P = 10 ### the moment the animation is still
w1 = P/L ; w2 = 1-w1 ### 2 weights : 25% - 75% if L = 40
noise = round(uniform(-1,1)/15,2) ### why not create some noise ?
bound = (T1 < F < T2 ) ### noise time span
player["frame_pos"] = (noise*bound) + w1*L/(1+exp(-K1*(F-T1))) + w2*L/(1+exp(-K2*(F-T2)))
So the time X is player[‘frame_time’] and the output Y is player[“frame_pos”]
Where to use ??
- In Range 1.0 → … : you can use the Action Actuator with a Float property
- In Range 1.6 → … : with this new feature you can feed the “Speed”
!! Actually use the SPEED (see post below) and not the POSITION
KX_GameObject.setActionLayerSpeed(Layer, Speed)