How to make a Rayman style hover in 3D

I am working on a 3D Platformer where I want my character to start hovering if I press the jump button in mid-air, just like in Rayman 2.

I tried implementing it by lowering the gravity for the hover, but now when holding a direction the character flies a lot further than they should. It’s preserving too much momentum.

I don’t know whether to fine-tune the jump variables to try and fix this or go for a different approach like changing the character’s weight or applying a force below it, going upwards.

A quick video for you to get a gist of how the hover looks: Rayman 2 - Gamepad vs Keyboard Hover Distance Comparison - YouTube

It’s not a glide like Spyro, or Kazooie flapping her wings, it’s more of a controlled descent.

Personally, for something like this gliding, i would make the char ignoring gravity during the glide phase, and let him move downward in a diagonal way at a constant speed and angle, until the button is released or he lands.
Also any normal movement by the directional keys should be disabled during glide, he should only be able to rotate, and the glide movement then would just continue in the new direction.

1 Like

The good memories I have about Rayman 2 :).

What if you create a float variable which is 1 when walking and 0.5 when hovering?
You’d use this variable to multiply the movement input with (from the axis input binding), so that the input becomes halved while hovering. Combine this with lowered gravity and you should get the same results as Rayman 2.

This is how I think rayman does it. Rayman doesn’t glide, he is 1:1 reactive to rotation input but the movement speed is lowered.

2 Likes

This wouldn’t work, because you’re describing a glide, which is not what is intended.

Didn’t think of lowering the move speed. Might just be what I need. After testing I’ll reply.

Well, a glide is what i see in your linked video ^.^ Ok, if it is just slowly falling, and you can move slowly too during hover, then still, ignore gravity, make it constantly move downward, but also allow slow movements in other directions.

2 Likes

This kind of feels like it (hard to judge has the flip at the height of the jump and the hover animation adds a lot to the feel), maybe with tweaking it will work.
I had to kill all momentum before starting the hover so the character wouldn’t fly really far.
Sometimes, when I start hovering, I gain a little bit of altitude due to the reduced gravity. And I don’t like it, mainly due to how random it feels. Any way to fix that?

EDIT: I guess the better way to describe it is that even changing the gravity, it still reaches the jump apex, even when I stop the jump and kill all movement.

1 Like

I see you modify the gravity here depending on the hovering state but I don’t see a modification in movement speed / movement input multiplier. Did that not work out?

This is always the case with movement, but rayman 2-like animation might be an exception. movement in rayman 2 feels very responsive to the point that the character often moves 1:1 to the gamepad input with no additional interpolation.

I can’t say without implementing this system myself, character movement can be a complex beast. But if the character still gains altitude after you stop jumping to enter hover state, that would sound odd. Have you tried setting movement mode to none during hover? When you set it to none you can implement your own movement state.

*Edit I’m not diving in the code atm (it’s night already here) but another thought I had is modifying the max jump height / speed during the hover state. The character movement component has the following property:

/** Initial velocity (instantaneous vertical acceleration) when jumping. */
UPROPERTY(Category="Character Movement: Jumping / Falling", EditAnywhere, BlueprintReadWrite, meta=(DisplayName="Jump Z Velocity", ClampMin="0", UIMin="0"))
float JumpZVelocity;

You could try setting JumpZVelocity to 0 during hover and test if this flattens the jump curve.

1 Like

The problem is that if I try to hover before reaching the jump apex, as gravity gets lighter, the momentum propels the character higher.
Even by attempting to stop the jump, setting the velocity to 0, or killing the momentum, it keeps happening.
I wonder if I have to see the gravity on the next frame or something.
And I was changing the movement speed, I just didn’t include it in the picture.


Hope the code isn’t too small to read. Up top is a code I’m working on for a crouch jump (which also isn’t working, but that’s another topic).

1 Like

There are a few methods on the charactermovementcomponent which might help us here:

/** Clears forces accumulated through AddImpulse() and AddForce(), and also pending launch velocity. */
UFUNCTION(BlueprintCallable, Category="Pawn|Components|CharacterMovement")
virtual void ClearAccumulatedForces();

And this one:

	/** 
 * Add impulse to character. Impulses are accumulated each tick and applied together
 * so multiple calls to this function will accumulate.
 * An impulse is an instantaneous force, usually applied once. If you want to continually apply
 * forces each frame, use AddForce().
 * Note that changing the momentum of characters like this can change the movement mode.
 * 
 * @param	Impulse				Impulse to apply.
 * @param	bVelocityChange		Whether or not the impulse is relative to mass.
 */
UFUNCTION(BlueprintCallable, Category="Pawn|Components|CharacterMovement")
virtual void AddImpulse( FVector Impulse, bool bVelocityChange = false );

If clearing the forces does not work, try adding an one time impulse, opposite to the current character velocity to “push it down”. I hope that gives you the instant hover effect rayman does, without pushing you upward when gravity changes.

1 Like

I fixed this by following this tutorial: How To Create A Hand Glider - Unreal Engine Tutorial - YouTube
Now I simply set the gravity to 0 and apply a constant velocity down.
I also decrease the movement speed on the X and Y components.
I’m adjusting the variables a bit, but this is what I wanted!


1 Like