IsFalling in C++

Hello !

I am trying to create the IsFalling Blueprint function in C++.

Here is my header file:

// Kevin-Brandon Corbett 2019

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "JetPackChar.generated.h"

UCLASS()
class GAMEMECHANICS_API AJetPackChar : public ACharacter
{
	GENERATED_BODY()

public:
	// Sets default values for this character's properties
	AJetPackChar();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

	// Called to bind functionality to input
	virtual void SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) override;

	// Handles input for moving forward and backwards
	UFUNCTION()
	void MoveForward(float Value);
	
	// Handles input for moving right and left
	UFUNCTION()
	void MoveRight(float Value);

	// Handles input for jumping
	void Jump(float Value);

	bool IsFalling();

	bool IsInAir();

	// Target is Character Movement Component
	virtual void SetMovementMode
	(
		EMovementMode NewMovementMode,
		uint8 NewCustomMode
	);

private:
	bool bSpaceBar;
	bool bIsUsingJet;
	bool bIsFlying;

	const bool bFalling;

	UCharacterMovementComponent* CharacterMovement;
};

and now here is my cpp file:

// Kevin-Brandon Corbett 2019


#include "JetPackChar.h"
#include "Components/InputComponent.h"
#include "Camera/CameraComponent.h"
#include "GameFramework/CharacterMovementComponent.h"


// Sets default values
AJetPackChar::AJetPackChar()
{
 	// Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

}

// Called when the game starts or when spawned
void AJetPackChar::BeginPlay()
{
	Super::BeginPlay();
	
}

// Called every frame
void AJetPackChar::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

// Called to bind functionality to input
void AJetPackChar::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	// set up gameplay key bindings
	check(PlayerInputComponent);

	Super::SetupPlayerInputComponent(PlayerInputComponent);

	// Bind jump events
	PlayerInputComponent->BindAxis("Jump", this, &AJetPackChar::Jump);

	// Set up "movement" bindings
	PlayerInputComponent->BindAxis("MoveForward", this, &AJetPackChar::MoveForward);
	PlayerInputComponent->BindAxis("MoveRight", this, &AJetPackChar::MoveRight);

	
	

}

void AJetPackChar::MoveForward(float Value)
{
	// Find out which way is "forward" and record that the player wants to move that way.
	FVector Direction = FRotationMatrix(GetControlRotation()).GetScaledAxis(EAxis::X);
	AddMovementInput(Direction, Value);
}

void AJetPackChar::MoveRight(float Value)
{
	// Find out which way is "right" and record that the player wants to move that way.
	FVector Direction = FRotationMatrix(GetControlRotation()).GetScaledAxis(EAxis::Y);
	AddMovementInput(Direction, Value);
}

void AJetPackChar::Jump(float Value)
{
	bSpaceBar = true;
	if (GetCharacterMovement()->IsFalling())
	{
		UE_LOG(LogTemp, Warning, TEXT("You are falling!"));
		if (bIsUsingJet)
		{
			UE_LOG(LogTemp, Warning, TEXT("You are flying using the JetPack!"));
		}
		else
		{
			// If we are not flying already then set our movement mode so that we are  
			GetCharacterMovement()->SetMovementMode(MOVE_Flying);
			bIsFlying = true;
			bIsUsingJet = true;
		}
	}
	
}

bool AJetPackChar::IsFalling()
{
	if (!IsInAir)
	{
		return true;
	}
	else
	{
		return false;
	}
}

void AJetPackChar::SetMovementMode(EMovementMode NewMovementMode, uint8 NewCustomMode)
{

}

bool AJetPackChar::IsInAir()
{
	const bool bFalling = (GetCharacterMovement()->SetMovementMode == EMovementMode::MOVE_Falling);
}


I’ve tried messing around with different functions and variables but I can’t get any of it to work. It seems really easy and I’m going to keep trying to figure it out. I wanted to ask to see if anyone knew how and could explain it to me.

Thank you! I appreciate it!

So far I used this code to make it work.


bool AJetPackChar::IsFalling()
{
	if (&UCharacterMovementComponent::FindFloor)
	{
		return false;
	}
	else
	{
		return true;
	}
}

Now when I use IsFalling in:

void AJetPackChar::Jump(float Value)
{
	bSpaceBar = true;
	if (GetCharacterMovement()->IsFalling())
	{
		UE_LOG(LogTemp, Warning, TEXT("You are falling!"));
		if (bIsUsingJet)
		{
			UE_LOG(LogTemp, Warning, TEXT("You are flying using the JetPack!"));
		}
		else
		{
			// If we are not flying already then set our movement mode so that we are  
			GetCharacterMovement()->SetMovementMode(MOVE_Flying);
			bIsFlying = true;
			bIsUsingJet = true;
		}
	}
	else
	{
		if (bIsFlying)
		{
			UE_LOG(LogTemp, Warning, TEXT("You are flying!"))
		}
		else
		{
			LaunchCharacter(FVector(0, 0, 400), false, false);
		}
	}
	
}

it works for now. I still need to refactor it so it is the best possible code while keeping everything clean, simple and easy to understand.

You don’t need to add a character movement component, you already have one as it’s inherited by ACharacter.

Secondly you don’t need to implement it

GetMovementComponent()->IsFalling()

All blueprint functions have C++ equivalents and most of the times it’s the exact same function which is the case here.


Just noticed that you’re already using it so now I’m confused. I guess I misunderstood what you’re trying to do? :confused:

1 Like

Thank you for the first part! I didn’t actually know that.

I think in my experimenting I discovered the C++ equivalent which might be the reason you are confused.

The problem is I wanted to recreate the IsFalling function that you would find in Blueprints. I think I solved it but i’m not sure if what I wrote returns true if currently falling (not flying, in a non-fluid volume, and not on the ground)

Well GetCharacterMovement()->IsFalling() is what you would find in blueprint. Specifically this
2019-10-23%2010_42_08-Escape%20-%20Unreal%20Editor

UCharacterMovementComponent::IsFalling() is just

return (MovementMode == MOVE_Falling) && UpdatedComponent;

Also note that you aren’t using the function you implemented in the snippet you showed above.

1 Like

Yeah I didn’t think so. Anyways thank you for the help I have a better understanding now. :smiley:

Oh and I forgot to mention that this expression is always true

if (&UCharacterMovementComponent::FindFloor)
1 Like

Thank you! :pray:t3: