My editor is crashing after a few seconds of playing in the editor, everything is extremely slow, i originally wanted to implement a simple setup, where i check my speed, if it’s above 0.01, than i want to increase my rotation rate, if the speed is not above or below, i want to decrease back to the start value of the rotation rate.
maybe i am missing something, maybe it’s a design thing because i am trying to implement something that is originally made in blueprints…
here is the class implementation :
HEADER:
#pragma once
#include "CoreMinimal.h"
#include "Components/TimelineComponent.h"
#include "GameFramework/Character.h"
#include "CPP_Character.generated.h"
class UCurveFloat;
UCLASS()
class SHOOTERTEMPLATE_API ACPP_Character : public ACharacter
{
GENERATED_BODY()
private:
//***************************************************************************
/** Components **/
//***************************************************************************
class UCharacterMovementComponent* MoveComp;
class UCapsuleComponent* CapsuleComp;
class USkeletalMeshComponent* CharacterMesh;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Testing AND Debug", meta = (AllowPrivateAccess = "true"))
class USkeletalMesh* MannequinMesh;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Camera", meta = (AllowPrivateAccess = "true"))
class UCameraComponent* FP_Camera;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly,Category = "Camera", meta = (AllowPrivateAccess = "true"))
class UCameraComponent* DebugCamera;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly,Category = "Camera", meta = (AllowPrivateAccess = "true"))
class USpringArmComponent* SpringArm;
// Sets default values for this character's properties
ACPP_Character();
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(class UInputComponent* PlayerInputComponent) override;
//***************************************************************************
/** Variables **/
//***************************************************************************
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Movement")
bool bIsJumping;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Movement")
bool bIsRunning;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Movement")
bool bIsSprinting;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Movement")
bool bIsCrouching;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Movement")
bool bIsStrafing;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Camera")
bool bDebugCamON;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Camera")
bool bIsTurningRight;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Camera")
bool bIsTurningLeft;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Camera")
bool bIsSlowMotionON;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Camera")
bool bDebugMesh;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Movement")
float BaseTurningRate;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Movement")
float BaseLookUpRate;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Movement")
float ForwardInput;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Movement")
float SideInput;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Movement")
float InputSpeed;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Movement")
float Direction;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Movement")
float MouseLeftRightAxisValue;
// Editable Variables in Blueprints
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Testing AND Debug")
float SlowMotionRate;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Testing AND Debug")
float DebugCamOffsetAmount;
FRotator DeltaDirection;
FVector MovementVec;
//***************************************************************************
/** Functions **/
//***************************************************************************
void MoveForwardBackward(float value);
void MoveRightLeft(float value);
void TurnRightLeft(float value);
void LookUpDown(float value);
void StartCrouch();
void StopCrouch();
void StartJump();
void StopJump();
void StartSprint();
void StopSprint();
void ToggleRunWalk();
void ToggleCamera();
void StrafingON();
void StrafingOFF();
void ToggleSlowMotion();
void ToggleMesh();
void StartAimDownSight();
void StopAimDownSight();
//***************************************
/** Timelines **/
//***************************************
FTimeline DecreaseRotRateTimeline;
FTimeline IncreaseRotRateTimeline;
UPROPERTY(EditAnywhere,Category = "Timeline")
UCurveFloat* ResetRotRateCurveFloat;
UPROPERTY(EditAnywhere,Category = "Timeline")
UCurveFloat* IncreaseRotRateCurveFloat;
UFUNCTION()
void ResetRotRateProgress(float value);
UFUNCTION()
void IncreaseRotRateProgress(float value);
};
CPP:
// Fill out your copyright notice in the Description page of Project Settings.
#include "CPP_Character.h"
#include "Components/InputComponent.h"
#include "Components/CapsuleComponent.h"
#include "Components/TimelineComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.h"
#include "Kismet/KismetSystemLibrary.h"
#include "Kismet/KismetMathLibrary.h"
#include "Kismet/GameplayStatics.h"
#include "AnimInstance_Character.h"
// Sets default values
ACPP_Character::ACPP_Character()
{
// 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;
// Getting Native Inherited Components From ACharacter
MoveComp = GetCharacterMovement();
CapsuleComp = GetCapsuleComponent();
CharacterMesh = GetMesh();
// Setting Up Components
SpringArm = CreateDefaultSubobject<USpringArmComponent>("SpringArm");
SpringArm->SetupAttachment(this->GetMesh());
SpringArm->TargetArmLength = 150.f;
SpringArm->SocketOffset = FVector(0.f, DebugCamOffsetAmount, 0.f);
SpringArm->bUsePawnControlRotation = true;
SpringArm->bEnableCameraLag = true;
SpringArm->bEnableCameraRotationLag = true;
SpringArm->CameraLagSpeed = 50.f;
SpringArm->CameraRotationLagSpeed = 50.f;
SpringArm->CameraLagMaxDistance = 10.f;
DebugCamera = CreateDefaultSubobject<UCameraComponent>("DebugCamera");
DebugCamera->SetupAttachment(SpringArm);
DebugCamera->SetActive(false);
DebugCamera->bAutoActivate = false;
DebugCamera->bUsePawnControlRotation = false;
FP_Camera = CreateDefaultSubobject<UCameraComponent>("FP_Camera");
FP_Camera->SetActive(true);
FP_Camera->AttachToComponent(this->GetMesh(), FAttachmentTransformRules::KeepRelativeTransform, TEXT("headSocket"));
FP_Camera->bUsePawnControlRotation = true;
// Setting Up Variables
bUseControllerRotationYaw = true;
MoveComp->bOrientRotationToMovement = true;
MoveComp->bUseControllerDesiredRotation = false;
MoveComp->RotationRate = FRotator(0.f,0.f,50.f);
BaseTurningRate = 45.f;
BaseLookUpRate = 45.f;
bIsJumping = false;
bIsRunning = false;
bIsSprinting = false;
bIsCrouching = false;
bIsStrafing = true;
bDebugCamON = false;
bIsTurningRight = false;
bIsTurningLeft = false;
bIsSlowMotionON = false;
MovementVec = { 0.f,0.f,0.f };
DebugCamOffsetAmount = 50.f;
DecreaseRotRateTimeline.SetTimelineLength(2.f);
IncreaseRotRateTimeline.SetTimelineLength(2.f);
}
// Called when the game starts or when spawned
void ACPP_Character::BeginPlay()
{
Super::BeginPlay();
if (IncreaseRotRateCurveFloat)
{
FOnTimelineFloat TimelineProgress;
TimelineProgress.BindUFunction(this, FName("IncreaseRotRateProgress"));
IncreaseRotRateTimeline.AddInterpFloat(IncreaseRotRateCurveFloat, TimelineProgress);
IncreaseRotRateTimeline.SetLooping(false);
}
if (ResetRotRateCurveFloat)
{
FOnTimelineFloat TimelineProgress;
TimelineProgress.BindUFunction(this, FName("ResetRotRateProgress"));
DecreaseRotRateTimeline.AddInterpFloat(ResetRotRateCurveFloat, TimelineProgress);
DecreaseRotRateTimeline.SetLooping(false);
}
}
// Called every frame
void ACPP_Character::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
IncreaseRotRateTimeline.TickTimeline(DeltaTime);
DecreaseRotRateTimeline.TickTimeline(DeltaTime);
}
// Called to bind functionality to input
void ACPP_Character::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
// **replace with enhanced input**
InputComponent->BindAction("Crouch", IE_Pressed, this, &ACPP_Character::StartCrouch);
InputComponent->BindAction("Crouch", IE_Released, this, &ACPP_Character::StopCrouch);
InputComponent->BindAction("Sprint", IE_Pressed, this, &ACPP_Character::StartSprint);
InputComponent->BindAction("Sprint", IE_Released, this, &ACPP_Character::StopSprint);
InputComponent->BindAction("Jump", IE_Pressed, this, &ACPP_Character::StartJump);
InputComponent->BindAction("Jump", IE_Released, this, &ACPP_Character::StopJump);
InputComponent->BindAction("ToggleWalk/Run", IE_Pressed, this, &ACPP_Character::ToggleRunWalk);
InputComponent->BindAction("ToggleDebugCam", IE_Pressed, this, &ACPP_Character::ToggleCamera);
InputComponent->BindAction("ToggleSlowMotion", IE_Pressed, this, &ACPP_Character::ToggleSlowMotion);
InputComponent->BindAction("ToggleMesh", IE_Pressed, this, &ACPP_Character::ToggleMesh);
InputComponent->BindAction("AimDownSight", IE_Pressed, this, &ACPP_Character::StartAimDownSight);
InputComponent->BindAction("AimDownSight", IE_Released, this, &ACPP_Character::StopAimDownSight);
InputComponent->BindAxis("Move Forward / Backward", this, &ACPP_Character::MoveForwardBackward);
InputComponent->BindAxis("Move Right / Left", this, &ACPP_Character::MoveRightLeft);
InputComponent->BindAxis("Turn Right / Left Mouse", this, &ACPP_Character::TurnRightLeft);
InputComponent->BindAxis("Look Up / Down Mouse", this, &ACPP_Character::LookUpDown);
}
void ACPP_Character::StartCrouch()
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Orange, TEXT("Crouching"));
}
if (MoveComp->IsMovingOnGround())
{
bIsCrouching = true;
}
}
void ACPP_Character::StopCrouch()
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Orange, TEXT("Standing"));
}
if (bIsCrouching)
{
bIsCrouching = false;
}
}
void ACPP_Character::StartJump()
{
if (!bIsJumping && !MoveComp->IsFalling())
{
ACharacter::Jump();
bIsJumping = true;
}
else if (MoveComp->IsFalling())
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Orange, TEXT("In Air"));
}
}
}
void ACPP_Character::StartSprint()
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Orange, TEXT("Sprinting"));
}
if (MoveComp->IsMovingOnGround())
{
bIsSprinting = true;
}
}
void ACPP_Character::StopSprint()
{
FString temp;
if (bIsRunning)
{
temp = "Running";
}
else { temp = "Walking"; }
if (GEngine)
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Orange, temp);
if (bIsSprinting)
{
bIsSprinting = false;
}
}
void ACPP_Character::StopJump()
{
if (bIsJumping && MoveComp->IsFalling())
{
ACharacter::StopJumping();
bIsJumping = false;
}
}
void ACPP_Character::ToggleRunWalk()
{
if (bIsRunning)
{
bIsRunning = false;
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Orange, TEXT("Walking"));
}
}
else
{
bIsRunning = true;
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Orange, TEXT("Running"));
}
}
}
void ACPP_Character::MoveForwardBackward(float value)
{
UKismetSystemLibrary::PrintString(GetWorld(),
FString::Printf(TEXT("Forward / Backward Input: %f"), value), true, true, FColor::Green, 0.f);
if (value != 0)
{
MovementVec.Z = 0;
MovementVec.Y = 0;
MovementVec.X = value;
ForwardInput = value;
AddMovementInput(GetActorForwardVector(), ForwardInput);
}
else
{
ForwardInput = 0;
}
// A
FRotator DebugCamRot = DebugCamera->GetComponentRotation();
// B
FRotator CapsuleRot = CapsuleComp->GetComponentRotation();
// Delta & A
FRotator DeltaDebugCapsule = DebugCamRot - CapsuleRot;
// B
FRotator MovementRot = UKismetMathLibrary::MakeRotFromX(MovementVec);
// Delta Final
DeltaDirection = DeltaDebugCapsule - MovementRot;\
Direction = DeltaDirection.Yaw;
UKismetSystemLibrary::PrintString(GetWorld(),
FString::Printf(TEXT("Direction Of Movement: %f"), Direction), true, true, FColor::Green, 0.f);
// do n variables
int8_t n = 1; // Number of times to "do"
int8_t i = 0; // Counter variable
UAnimInstance_Character* AnimInstance_REF = Cast<UAnimInstance_Character>(CharacterMesh->GetAnimInstance());
if (AnimInstance_REF->Speed > 0.01f)
{
do
{
IncreaseRotRateTimeline.PlayFromStart();
i++;
} while (i < n);
}
else
{
DecreaseRotRateTimeline.Play();
n = 0;
}
}
void ACPP_Character::MoveRightLeft(float value)
{
UKismetSystemLibrary::PrintString(GetWorld(),
FString::Printf(TEXT("Right / Left Input: %f"), value), true, true, FColor::Green, 0.f);
if (value != 0)
{
MovementVec.Z = 0;
MovementVec.X = 0;
MovementVec.Y = value * -1;
SideInput = value;
AddMovementInput(GetActorRightVector(), SideInput);
}
else
{
SideInput = 0;
}
}
void ACPP_Character::TurnRightLeft(float value)
{
MouseLeftRightAxisValue = value;
AddControllerYawInput(value * BaseTurningRate * GetWorld()->GetDeltaSeconds());
if (MouseLeftRightAxisValue == 0.f)
{
bIsTurningRight = false;
bIsTurningLeft = false;
}
if (MouseLeftRightAxisValue > 0.f)
{
bIsTurningRight = true;
}
else bIsTurningRight = false;
if (MouseLeftRightAxisValue < 0.f)
{
bIsTurningLeft = true;
}
else bIsTurningLeft = false;
}
void ACPP_Character::LookUpDown(float value)
{
AddControllerPitchInput(value * BaseLookUpRate * GetWorld()->GetDeltaSeconds());
}
void ACPP_Character::ToggleCamera()
{
if (!bDebugCamON)
{
bDebugCamON = true;
DebugCamera->SetActive(true);
FP_Camera->SetActive(false);
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Orange, FString::Printf(TEXT("DEBUG CAM ON; Strafing: %d"),bIsStrafing));
}
StrafingOFF();
}
else
{
bDebugCamON = false;
DebugCamera->SetActive(false);
FP_Camera->SetActive(true);
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Orange, FString::Printf(TEXT("First-Person CAM ON; Strafing: %d"), bIsStrafing));
}
StrafingON();
}
}
void ACPP_Character::StrafingON()
{
MoveComp->bUseControllerDesiredRotation = true;
MoveComp->bOrientRotationToMovement = false;
bUseControllerRotationYaw = true;
bIsStrafing = true;
}
void ACPP_Character::StrafingOFF()
{
MoveComp->bUseControllerDesiredRotation = false;
MoveComp->bOrientRotationToMovement = true;
bUseControllerRotationYaw = false;
bIsStrafing = false;
}
void ACPP_Character::ToggleSlowMotion()
{
if (!bIsSlowMotionON)
{
// slowmo
UGameplayStatics::SetGlobalTimeDilation(GetWorld(), SlowMotionRate);
bIsSlowMotionON = true;
}
else
{
// slowmo off
UGameplayStatics::SetGlobalTimeDilation(GetWorld(), 1.f);
bIsSlowMotionON = false;
}
}
void ACPP_Character::ToggleMesh()
{
if (!bDebugMesh)
{
// set UE4 mannequin as the mesh
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Orange, TEXT("Debug Mesh ON"));
bDebugMesh = true;
}
}
else
{
// set custom mesh for character
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Orange, TEXT("Custom Mesh ON"), bDebugMesh);
bDebugMesh = false;
}
}
}
void ACPP_Character::StartAimDownSight()
{
// Hold Aim Down Sight
if (DebugCamera->IsActive())
{
StrafingON();
bIsStrafing = true;
}
}
void ACPP_Character::StopAimDownSight()
{
// Release Aim Down Sight
if (DebugCamera->IsActive())
{
StrafingOFF();
bIsStrafing = false;
}
}
void ACPP_Character::IncreaseRotRateProgress(float value)
{
if (IncreaseRotRateCurveFloat)
{
IncreaseRotRateTimeline.PlayFromStart();
float CurrentYaw = GetCharacterMovement()->RotationRate.Yaw;
float newYaw = value;
float Alpha = 1;
float LerpedYaw = FMath::Lerp(CurrentYaw, newYaw, Alpha);
if (GEngine)
GEngine->AddOnScreenDebugMessage(-1, -1.f, FColor::Blue,
FString::Printf(TEXT("Rotation Rate: %f"), CurrentYaw));
GetCharacterMovement()->RotationRate.Yaw = LerpedYaw;
}
}
void ACPP_Character::ResetRotRateProgress(float value)
{
if (ResetRotRateCurveFloat)
{
float CurrentYaw = GetCharacterMovement()->RotationRate.Yaw;
float newYaw = value;
float Alpha = 0.1f;
float LerpedYaw = FMath::Lerp(CurrentYaw, newYaw, Alpha);
if (GEngine)
GEngine->AddOnScreenDebugMessage(-1, -1.f, FColor::Blue,
FString::Printf(TEXT("Rotation Rate: %f"), CurrentYaw));
GetCharacterMovement()->RotationRate.Yaw = LerpedYaw;
}
}