Retrigger Input Functions?

Hey! I have a small problem with the input in UE4. For example: My player is jumping, and the player presses crouch while in air. I dont want the player to crouch midair obviously, but as soon as the player has landed, he is not going to crouch. Anyone know what the problem is? At the same time, when I press crouch and the player walks off a ledge, they will be crouching midair.

Perhaps looking at the FPS tutorial might help you? Link
They use sth. like:

if (CharacterMovement->IsMovingOnGround() || CharacterMovement->IsFalling())
{
}

So you might want to check for those flags in your OnCrouchPressed() method?

Yes, but when the player is in the air and they are pressing “crouch”, the function is not triggered when they land on the floor. That is what I wanted to do.

You can override the method

virtual void ACharacter::OnLanded(const FHitResult& Hit)

in your AFPSCharacter. This function will be called when your character hits the ground. Just check for any pending “crouch events” (save your crouch request in a bool while the player is jumping and evaluate it in your OnLand implementation). Hope this helps?

Haha I actually tried it, but it only calls the function for a second or so (because thats how long “OnLanded” lasts). Hence why I need to use “Tick” to call it for a longer time.

I’ve tried it myself and it seems to be working :slight_smile:

Here is my code:

// input "Crouch" mapped to these functions
void AFPSCharacter::OnCrouchStart()
{
	if (CharacterMovement->IsFalling())
	{
		_crouchRequest = true;
		GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Yellow, TEXT("save crouch request"));
	}
	else
	{
		Crouch();
		GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Yellow, TEXT("crouch"));
	}
}
void AFPSCharacter::OnCrouchStop()
{
	_crouchRequest = false;
	UnCrouch();
}
// override from ACharacter::OnLanded(..)
void AFPSCharacter::OnLanded(const FHitResult& Hit)
{
	if (_crouchRequest)
	{
		_crouchRequest = false;
		Crouch();
		GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Yellow, TEXT("landed + pending crouch"));
	}
}

where _crouchRequest is a simple bool inside my character.

So while jumping and pressing crouch nothing happens, but OnLanded(…) my character immediately starts crouching (if crouch is still pressed). If this doesn’t work, I might have misunderstood your problem :wink:

You seem to be addressing it perfectly, but it just doesn’t work for me (keep in mind, I am using 4.1). Here is what I have (or used to have, as it doesnt work for me):

//Using walking as an example, cause its a lot less complex but works the same way
void AInstinctCharacter::Landed(const FHitResult& Hit)
{
	// make sure the parent class still does its things
	Super::Landed(Hit);

	if(hasPressedWalk == true)
		{
		hasPressedWalk = false;
		ChangeWalkMode();
		}
}

void AInstinctCharacter::ChangeWalkMode()
{
	hasPressedWalk = true;
	if (CharacterMovement->IsMovingOnGround())
	{
		CharacterMovement->MaxWalkSpeed = plWalkSpeed;
		plMomentum = 0;
	}
	else
	{
		CharacterMovement->MaxWalkSpeed = plMaxSpeed;
	}
}

void AInstinctCharacter::ResetWalkMode()
{
	hasPressedWalk = false;
	CharacterMovement->MaxWalkSpeed = plMaxSpeed;
}

There are some problems with your code:

First of all you don’t override the method “OnLanded” but one called “Landed()” but it should be ok. I have always used OnLanded so I’m not 100% sure.

Second in “ChangeWalkMode()” you reset hasPressedWalk to true but as I can’t see your other code, this could be a problem (just be sure it is correct).

Minor: “ResetWalkMode()” is never called, at least from what you posted. So I can’t say if it is correct (depending on your other code and where you call it) or not.

And finally (the actual problem): “OnLanded(…)” is being called immediatly when you hit the ground, even before “CharacterMovement->IsMovingOnGround() == true”. So if you call “ChangeWalkMode()” from inside “OnLanded(…)” your speed will always default to plMaxSpeed. Try setting MaxWalkSpeed and plMomentum inside your OnLanded method. This should do the trick.

I find a good method to debug such problems is to add some outputs to your code to see what happens and in which order (see my code above). Only if this doesn’t help I start really debugging my code by setting breakpoints to get some insights :slight_smile:

Hope this helps?

Alright thanks for the tipps. Change-and ResetWalkMode are just called by pressing or releasing shift (it did not seem THAT relevant for me to post it so i wanted to save space). But yes, this actually works! Thanks man, sorry that i did not get what you did there at first. I thought that calling the function was supposed to do the trick. Thanks for helping me with this small yet, in the long run, pretty important optimisation xD