Implementing jump

Hi All,
I’ve been trying to work this out for a while now, I have a pawn and I’m trying to make it jump.

Here’s what I have inside the jump function (there is no issue with how the function is set up so I will omit that):


Pawn->AddMovementInput(Pawn->GetActorUpVector(), 300.0f);

If I use this instead it snaps into mid air and descends slowly


Pawn->SetActorLocation(Pawn->GetActorUpVector() * 300.0f);

Although I don’t want it to snap to position, I would like it to ascend and descend at a smooth rate.

Any ideas?

I would take a look at the default Character first. Jumping can get really complicated. If you wanna yolo-swag it because it’s a super trivial jump or something, I suppose try doing that in a Tick function by smaller amounts until it reaches it’s current position + JumpHeight. Multiply by the delta so it’s frame rate independent. I STRONGLY recommend first looking at all the 10 billion details the default Character has to figure out how you will tackle those problems.

Love,
Tom

Everything to do with jumping is confined to the one function as is moving backwards, forwards and side to side. All they needed is:



Pawn->AddMovementInput(Pawn->GetActorForwardVector(), value);


You can basically do this in 2 ways either get the pawn’s mesh and add a impulse to the rootbone that is a one time call or add a force to the bone over a tick .

Add Impulse Doc :

no more casting required in newer version of engine but if you are using the old version you have to cast it to primitive component .


YourMEsh->AddImpulse(UpVector*impulseAmount, yourBone , true);

you can still achieve the same result using addforce by calculating the variable force
doc :UPrimitiveComponent::AddForce | Unreal Engine Documentation

Is there a way to do this to the capsule component?

This is really a hacky and unprofessional way of doing it, Jumping is already implemented in UE4, and it’s actually quite simple to use, your functions should look like this:

and you need to bind it in the SetupPlayerInputComponent functions like follows:

Essentially there are lots of things you can improve in this system, if you want to tweak the jumping velocity and the time it takes to be closer to real life what you can do is add this to your character constructor:

3 Likes

Unfortunately I don’t have the option to use bPressedJump.

Here’s an idea of what I’m doing, this is the Game Mode:



#include "TheGameCharacterTest.h"
#include "TheGameCharacterTestGameMode.h"
#include "CharacterClasses/MainCharacter.h"
#include "CharacterControllers/MainCharacterKeyboard.h"
#include "CharacterControllers/MainCharacterGamepad.h"

ATheGameCharacterTestGameMode::ATheGameCharacterTestGameMode()
{
	DefaultPawnClass = AMainCharacter::StaticClass();
	PlayerControllerClass = AMainCharacterKeyboard::StaticClass();
}


And the Keyboard Controller:



void AMainCharacterKeyboard::BeginPlay()
{
	Super::BeginPlay();

	APawn* Pawn = GetPawn();
	this->Possess(Pawn);
}


Then I’m able to do stuff like this:



void AMainCharacterKeyboard::MoveX(float Value)
{
        if (Sprinting) Value *= 2.0f;
	if (MovementDebug) GEngine->AddOnScreenDebugMessage(-1, 0.005f, FColor::Green, FString::Printf(TEXT("Moveing X %f"), Value));
	
	if (Value != 0.0f && (Pawn != NULL))
	{
		// add movement in that direction
		Pawn->AddMovementInput(Pawn->GetActorForwardVector(), Value);
	}
}


The AMainCharacterKeyboard is a PlayerController and the AMainCharacter is a Character (although this is a Pawn when I retrieve it from the GameMode via GetPawn() in AMainCharacterKeyboard).

Ok I got it to work by casting it:



void AMainCharacterKeyboard::BeginPlay()
{
	Super::BeginPlay();

	ACharacter* Pawn = Cast<ACharacter>(GetPawn());
	//Pawn = GetPawn();
	this->Possess(Pawn);

	// sprint timer
	GetWorldTimerManager().SetTimer(SprintTimer, this, &AMainCharacterKeyboard::SprintTimerHandler, 1.0f, true);
};


Is there a better way to separate the Character and the character controls to how I’ve done it? Basically I want to have a class for every peripheral e.g. keyboard and controller and for them to automatically switch when the other is used.

What you have done (creating different PlayerControllers for Keyboard and other controls) is most likely the only way to achieve it, However I don’t understand why you want to separate those controls while you can handle them in just one Controller with a cleaner interface and without having to switch controllers? (Since to automatically switch controllers, and detect when a device is plugged/unplugged you would have to dig deeper, into the engine codes which is simply too much hassle for handling simple controls)

It’s more to separate it all more manageable, there is going to be a log of stuff going into each one too.

I do my jumps with rootmotion most of the times to get the correct “feels”