How to play different landing animations based on how long my character fell?

AnimGraph root:

My AnimGraph states: https://i.imgur.com/efY3ztM.png

My Event Graph: https://i.imgur.com/XwBEzka.png

I am using the z-axis of the Get Velocity node which decreases into negative values when my character begins to fall down. I set the Z_VelocityThreshold to -1 to try to always trigger it in my AnimGraph but it always executes Landing instead of GreaterHeightLanding and I can’t figure out why. I also tried setting the threshold to an actual value that I wanted which was -900, and the *Landing *animation always plays.
Note: The boolean CanEnterIdleAnim is the animation that will play in the GreaterHeightLanding state

What about something like this?:

Not tested, just concept…

I mean, it’s not horrible but the information you want is already all there before you actually fall…

One single line trace initiate by the falling animation via a notify can get you the distance to the floor.
Based on that you can then change the landing.

If you want to be perfect about it, do the trace ahead of the character by the speed in MS.
With a capsule the same size as the characters capsule component (width you can get away with a sphere).

the notify won’t be 100% time accurate, but it shouldn’t matter because you’ll be in a falling state for a few milliseconds anyway.

Mind you, wouldn’t work with moving platforms… :rolleyes:

Depends on the speed of the platform vs that of the character I guess.

Technically the capsule component is always tracing for the floor. Gives out a distance too.
you could piggyback on that to double check fringe cases.

or one super long sphil to just work via Overlap.
anytime it overlaps you get a result. (May be more expensive perhaps since the overlap check is on a per tick basis).

In fact, I would just have a copy of the capsule component checking ahead offset by the speed.

and/or try to pull out the actual animation time since the anim is on a loop for the falling state.

For instance this could be piggybacked as pure math on the AnimBP.
When is falling becomes true you start adding world delta to a variable. And you can then use that direct value to change the end state with >= nodes for the time.

likely way less expensive then all of the above options. And probably more accurate since it’s based on time…

Tl; Dr:
take from the code above, use it in anim BP.
start counting after the movement component “is falling” is true.
I’ll likely add a screencap tomorrow, I need to code something similar myself.

I tried doing different variations of your code but the first few milliseconds of the landing animation keeps playing on a loop due to the function timer and the fact that if I’m just walking on the ground (not falling) the float subtraction branch will keep executing (you also have the subtraction order reversed). I also tried adding it to my AnimBP as what [USER=“3140864”]MostHost LA[/USER] said with no luck. I really do like using time rather than what I initially did because I just realized that if I grab my z velocity when I’m not in the air, it will always be 0.

I do not completely understand the capsule component idea and would love to see a screenshot of an example. I didn’t go the line trace route basically because of what @ClockworkOcean said. Something could suddenly block my fall and my character would play the wrong landing animation when my line trace read 500uu and I actually fell 150uu.

The capsule idea would basically be another collision detection.
You create a collision capsule the same as the character in sizing, and offset it’s position at runtime based upon speed / direction. You want the capsule to always be where you Will eventually be. If something is present the overlap event will fire alerting you to it.
You’ll know (dependent on settings) around 5 frames ahead of time “where” you will land.
Which is actually important for predictive animation - though the issue there is far more complex.

Either way, since really all you need is time - to choose an animation - maybe a velocy to decide if you should roll or crash - you can do as I said last.
This is an example logic for it.


Thing is, Fall duration doesn’t tell you much of anything. Fall speed does.
You can get speed with the usual GetLastUpdate Velocity node. You should probably be getting it already for your blendspaces/walk speed. so just pin the Z into a new variable.

This value can go up -4000.000 in my current project.
That would be in fact terminal velocity (which is 5300 is cm per second, so it’s close enough I recon?) I think it’s controlled by the project settings actually. almost 100% positive you could set that to 5300 and force the “splat” animations off of it :stuck_out_tongue:

So anyway, to make a long story short. 1 variable. Check if it’s …

Ok backtrack off things I know off hand. Lethal fall distance is avg. of 50ft. to M that’s, around 12. 12m fall is a speed of around 15m per second without math - you can run this formula.
Square of (2 * 9.8m/s^2 * height of fall). 15m/s is 1500 units in unreal.
If the speed is <= -1500 you should use the dead animation.

Then, let’s say that 1/2 of that fall distance is the good distance for a paramilitary or assassin creed parkour enthusiast. that’s a mighty 6m fall.
The math on that I’d have to do so… 29.86=117 sqrt of that is 10 meters per second.

So if the speed is >= -1000.

from that,
death anim if <= -1000
Hard land between -800 and -1000
Mid Land between -700 to -800
soft land between 0 to -700

To do that, I’d convert the jump land state to it’s own state machine, and select the state I want to use based on the speed itself. No overhead. 1 variable.
Screw time. it’s a function of speed because of gravity.

Obviously if gravity change the values won’t hold true. You could script a function to re-caclculate those thresholds and call it at your pleasure depending on game play if you wanted to create something universal.

I personally used the CharacterMovementComponent and get the Velocity on the Z axis, after that I have preset 3 values which show how much damage or how hard the character fell.
I Created another Component for this So this can be used on multiple character Classes.

I know this is a BP Question but this still might help someone.


 [TABLE]

//Check if the Jump was High
 		

 
 			if (Owner->GetMovementComponent()->Velocity.Z <= -1300)
 		

 
 			{
 		

 
 			//DamageMeter Will Multiply With Total Damage Recived Below
 		

 
 			DamageMeter = Owner->GetMovementComponent()->Velocity.Z / -1800;
 		

 
 			ReceiveDamageWhenHitGround = true;
 		

 
 			}
 		

 
 			//Recieved Damage
 		

 
 			if (!Owner->GetMovementComponent()->IsFalling() && ReceiveDamageWhenHitGround)
 		

 
 			{
 		

 
 			UE_LOG(LogTemp, Log, TEXT("Damage Recieved upon landing"));
 		

 
 			//Add damage Function Here
 		

 
 			ReceiveDamageWhenHitGround = false;
 		

 
 			}
 		

 
 			//Check if the Jump was Medium
 		

 
 			if (Owner->GetMovementComponent()->Velocity.Z <= -600)
 		

 
 			{
 		

 
 			ToggleEffectForHighJump = true;
 		

 
 			}
 		

 
 			//Play The Effect For High Jumping
 		

 
 			if (!Owner->GetMovementComponent()->IsFalling() && !ReceiveDamageWhenHitGround && ToggleEffectForHighJump)
 		

 
 			{
 		

 
 			ToggleEffectForHighJump = false;
 		

 
 			GetWorld()->GetFirstPlayerController()->PlayerCameraManager->PlayCameraShake(JumpShake, 1.0f);
 		

 
 			UGameplayStatics::PlaySound2D(this, HighLandingSound, 5.0f);
 		

 
 			}
 		

 

How about binding to the MovementMode changed delegate. Just store the value of your current location when you enter the falling state and store the value of your location when you land. For example:

(It’s hard to get that all in one screenshot so the 2nd and 3rd images are just zoomed in on each state)

Here’s a quick vid, I’ve just set it so if the fall height is over 600 it goes to ragdoll:

[ATTACH=JSON]{“data-align”:“none”,“data-size”:“full”,“data-tempid”:“temp_184343_1582388395532_262”,“title”:“overview.png”}[/ATTACH]

[ATTACH=JSON]{“data-align”:“none”,“data-size”:“full”,“data-tempid”:“temp_184344_1582388372803_21”,“title”:“falling-state.png”}[/ATTACH]

[ATTACH=JSON]{“data-align”:“none”,“data-size”:“full”,“data-tempid”:“temp_184345_1582388358516_782”,“title”:“Landed.png”}[/ATTACH]

Thank you for all of your inputs. I went back to my original idea and came up with this logic which works. Knowing how simple this solution turned out, I believe I was overthinking it because I wanted the logic in my AnimGraph. But this works for now.

I don’t exactly know how to implement this especially using two state machines since I have never done that before but I like this idea. It would be nice to have this logic in my AnimGraph since I think it looks the most elegant but after more research/tinkering I’ll implement it that way. I’m still a rookie when it comes to the AnimGraph.

So this node executes the event every time my character goes into a different state? How do I specify a state? I guess I could just do a index-type logic knowing how my AnimGraph works but I thought there was a more elegant way. Also, your images are not showing up.
MovementNode.PNG

You can have tested state machines.
a state machine within a state machine.
so you go into the jump land and you create a new state machine, connect it, double click it to open it up, and create the 3 different states within it.

I’m setting one up on my main project. I have to take a bit to get some animations going, but I’ll share a vide for you once it is implemented.

The c++ code from Haris is very similar to my base idea. I just find it more elegant then any scripting since it really doesn’t require any (and I definitely need to focus more on movement animations myself).

The images arnt showing? Weird they do for me…they would explain everything :slight_smile:

That delegate gets automatically fired everytime the character movement state is changed so you can get an event everytime you jump/fall or land.

I think theres also one for when you’re at the apex of a jump. Id have to double check that in the code though

This is what I see:


I tested in Chrome, Firefox, mobile Safari, and Edge and disabled anything that would manipulate page elements like an ad blocker. It would be nice if you could upload them to an image hosting site like Imgur (which is free) if uploading images directly from your computer is not working.

weird works on all my devices, oh well won’t use that ‘upload to server’ option again :slight_smile:

jeez this image thing just keeps saying invalid URL… here’s the direct links to some image site:

This would only take into account falling, so it wouldn’t work if you want to take into account say being shot up high into the air but landing at the same height as you took off.

In fact I had UE open a minute ago and had a quick look. These events/delegates are probably more useful for you:

There’s an Event for OnLanded where you can fire off some custom code.

Also you could bind to the delegate ‘OnReachedJumpApex’ (make sure you set bNotifyApex = true in your character movement component)

Those above are good options too.
You could combine that to the speed variable way to create even more effects.

Thanks for the images. This is helpful!

Thanks a lot for the video! Adding a state machine in a state machine is actually conceptually easy. This is what I wanted to do from the very beginning. I do like the hack of nulling out that initial nested state.