How to change my CharacterMovementComponent

#Cast

just to add more info

UPuppetCharacterMovementComponent* MyPuppetMovement = Cast<UPuppetCharacterMovementComponent>(CharacterMovement);



 if(!MyPuppetMovement) return; 
    MyPuppetMovement->bSprint = false;

Ideally you’d store the casted version as Chrys says, in your .h file.

Hello,

So I am trying out ue4 and I want to create my own CharacterMovementComponent.

But when I try to access a variable (for example bSprint) inside my APuppetsCharacter, I will receive this error:

Error 1 error C2039: ‘bSprint’ : is not a member of ‘UCharacterMovementComponent’

This is my code:

Character:

// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.

#include "Puppets.h"
#include "PuppetsCharacter.h"
#include "PuppetCharacterMovementComponent.h"

//////////////////////////////////////////////////////////////////////////
// APuppetsCharacter

APuppetsCharacter::APuppetsCharacter(const class FPostConstructInitializeProperties& PCIP)
: Super(PCIP.SetDefaultSubobjectClass<UPuppetCharacterMovementComponent>(ACharacter::CharacterMovementComponentName))
{
      CharacterMovement->bSprint = false;
}

CharacterMovementComponent.cpp

#include "Puppets.h"
#include "PuppetCharacterMovementComponent.h"


UPuppetCharacterMovementComponent::UPuppetCharacterMovementComponent(const class FPostConstructInitializeProperties& PCIP)
	: Super(PCIP)
{
	RunSpeed = 400.f;
	WalkSpeed = 180.f;
	SprintJumpVelocity = 500.f;
	WalkJumpVelocity = 400.f;
	bSprint = false;
}

void UPuppetCharacterMovementComponent::InitializeComponent()
{
	Super::InitializeComponent();
}

//Tick Comp
void UPuppetCharacterMovementComponent::TickComponent(float DeltaTime,enum ELevelTick TickType,FActorComponentTickFunction *ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
}

CharacterMovementComponent.h

#pragma once

#include "GameFramework/CharacterMovementComponent.h"
#include "PuppetCharacterMovementComponent.generated.h"

/**
 * 
 */
UCLASS()
class UPuppetCharacterMovementComponent : public UCharacterMovementComponent
{
	GENERATED_UCLASS_BODY()

protected:

	virtual void InitializeComponent() OVERRIDE;

	virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) OVERRIDE;

public:

	UPROPERTY(Category = "Character Movement", EditAnywhere, BlueprintReadWrite)
	float RunSpeed;

	UPROPERTY(Category = "Character Movement", EditAnywhere, BlueprintReadWrite)
	float WalkSpeed;

	UPROPERTY(Category = "Character Movement", EditAnywhere, BlueprintReadWrite)
	float SprintJumpVelocity;

	UPROPERTY(Category = "Character Movement", EditAnywhere, BlueprintReadWrite)
	float WalkJumpVelocity;

	bool bSprint;
	
};

Why does this happen? I thought I could set the class of CharacterMovement to a custom class with PCIP.SetDefaultSubObjectClass. It doesn’t create any errors, apart from that I cannot access my variables.

EDIT: Ow and, I know setting the bSprint to false in the Character class doesn’t do anything when it is already set in the Component.cpp. Its was just to test whether or not I can access it.

I think your problem is that

CharacterMovement->bSprint = false;

actually refers to

	/** CharacterMovement component used by walking/running/flying avatars not using rigid body physics */
	UPROPERTY(Category=Character, VisibleAnywhere, BlueprintReadOnly)
	TSubobjectPtr<class UCharacterMovementComponent> CharacterMovement;

in the ACharacter class.

so the UCharacterMovementComponent ofc has no idea what bSprint is.

so either you cast it everytime to your movement class or you keep a pointer to your own puppet moment class which you cast once , in your

virtual void PostInitializeComponents();

like this you should be certain that the component exists and is valid.

after that in your custom code you can refer to it as

MyPuppetMovement->bSprint = false; 

hope that helps.
Chrys

Thanks I will take a look at it! I will comment again if I got it working!

I think I got it working!

I added

#include "PuppetCharacterMovementComponent.h"

and

public:

	UPuppetCharacterMovementComponent* MyPuppetMovement;

	virtual void PostInitializeComponents() OVERRIDE;

To my PuppetsCharacter.h

And I added

void APuppetsCharacter::PostInitializeComponents()
{
	Super::PostInitializeComponents();
	MyPuppetMovement = Cast<UPuppetCharacterMovementComponent>(CharacterMovement);
}

To my PuppetsCharacter.cpp

Final code for anyone interested how to create your own MovementComponent and creating an option to run when pressing shift in the ThirdPersonTemplate.
I took the ThirdPersonTemplate where I did not want the player to run automatically. So I set the CharacterMovement->MaxWalkSpeed to 180 when pressing W, and Interpolate it to 500 when pressing W+Shift. For me this was very helpful in learning to work with ue4 and C++ for the first time.

Note: Because most code is from the template, I deleted it here and put //TEMPLATE CODE there, otherwise my text is going to be long and confusing. But I did not delete anything of it in my own code, I just added the things you can see here:

PuppetsCharacter.cpp

// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.

#include "Puppets.h"
#include "PuppetsCharacter.h"
#include "PuppetCharacterMovementComponent.h"

//////////////////////////////////////////////////////////////////////////
// APuppetsCharacter

APuppetsCharacter::APuppetsCharacter(const class FPostConstructInitializeProperties& PCIP)
: Super(PCIP.SetDefaultSubobjectClass<UPuppetCharacterMovementComponent>(ACharacter::CharacterMovementComponentName))
{
	//TEMPLATE CODE
}

void APuppetsCharacter::PostInitializeComponents()
{
	Super::PostInitializeComponents();
	MyPuppetMovement = Cast<UPuppetCharacterMovementComponent>(CharacterMovement);
}
//////////////////////////////////////////////////////////////////////////
// Input

void APuppetsCharacter::SetupPlayerInputComponent(class UInputComponent* InputComponent)
{
	// TEMPLATE CODE
}


void APuppetsCharacter::TouchStarted(ETouchIndex::Type FingerIndex, FVector Location)
{
	// TEMPLATE CODE
}

void APuppetsCharacter::TurnAtRate(float Rate)
{
	// TEMPLATE CODE
}

void APuppetsCharacter::LookUpAtRate(float Rate)
{
	// TEMPLATE CODE
}

void APuppetsCharacter::MoveForward(float Value)
{
	// TEMPLATE CODE
}

void APuppetsCharacter::EnableSprint()
{
	if (MyPuppetMovement)
	{
		if (Controller != NULL && !MyPuppetMovement->bSprint)
		{
			MyPuppetMovement->bSprint = true;
		}
	}
}

void APuppetsCharacter::DisableSprint()
{
	if (MyPuppetMovement)
	{
		if (Controller != NULL && MyPuppetMovement->bSprint)
		{
			MyPuppetMovement->bSprint = false;
		}
	}
}

void APuppetsCharacter::MoveRight(float Value)
{
	// TEMPLATE CODE
}

void APuppetsCharacter::Tick(float DeltaTime)
{
	if (MyPuppetMovement)
	{
		float walkspeed = CharacterMovement->MaxWalkSpeed;

		if (MyPuppetMovement->bSprint && CharacterMovement->MaxWalkSpeed != MyPuppetMovement->RunSpeed)
		{
			walkspeed = FMath::FInterpTo(walkspeed, MyPuppetMovement->RunSpeed, DeltaTime, 5);
			CharacterMovement->JumpZVelocity = MyPuppetMovement->SprintJumpVelocity;
		}
		else if (!MyPuppetMovement->bSprint && CharacterMovement->MaxWalkSpeed != MyPuppetMovement->WalkSpeed)
		{
			walkspeed = FMath::FInterpTo(walkspeed, MyPuppetMovement->WalkSpeed, DeltaTime, 8);
			CharacterMovement->JumpZVelocity = MyPuppetMovement->WalkJumpVelocity;
		}

		CharacterMovement->MaxWalkSpeed = walkspeed;
	}
}

My PuppetsCharacter.h

// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
#pragma once

#include "GameFramework/SpringArmComponent.h"
#include "PuppetCharacterMovementComponent.h"
#include "PuppetsCharacter.generated.h"

UCLASS(config=Game)
class APuppetsCharacter : public ACharacter
{
	GENERATED_UCLASS_BODY()

	// TEMPLATE CODE

public:

	UPuppetCharacterMovementComponent* MyPuppetMovement;

	virtual void PostInitializeComponents() OVERRIDE;

protected:

	// TEMPLATE CODE

	/** Called for Sprint input */
	void EnableSprint();
	void DisableSprint();

	/** Override TICK*/
	void Tick(float DeltaTime) OVERRIDE;

protected:
	// TEMPLATE CODE
};

PuppetCharacterMovementComponent.cpp

// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.

#include "Puppets.h"
#include "PuppetCharacterMovementComponent.h"


UPuppetCharacterMovementComponent::UPuppetCharacterMovementComponent(const class FPostConstructInitializeProperties& PCIP)
	: Super(PCIP)
{
	RunSpeed = 400.f;
	WalkSpeed = 180.f;
	SprintJumpVelocity = 500.f;
	WalkJumpVelocity = 400.f;
	bSprint = false;
}

void UPuppetCharacterMovementComponent::InitializeComponent()
{
	Super::InitializeComponent();
}

//Tick Comp
void UPuppetCharacterMovementComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
}

PuppetCharacterMovementComponent.h

// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.

#pragma once

#include "GameFramework/CharacterMovementComponent.h"
#include "PuppetCharacterMovementComponent.generated.h"

/**
 * 
 */
UCLASS()
class UPuppetCharacterMovementComponent : public UCharacterMovementComponent
{
	GENERATED_UCLASS_BODY()

protected:

	virtual void InitializeComponent() OVERRIDE;

	virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) OVERRIDE;

public:

	UPROPERTY(Category = "Character Movement", EditAnywhere, BlueprintReadWrite)
	float RunSpeed;

	UPROPERTY(Category = "Character Movement", EditAnywhere, BlueprintReadWrite)
	float WalkSpeed;

	UPROPERTY(Category = "Character Movement", EditAnywhere, BlueprintReadWrite)
	float SprintJumpVelocity;

	UPROPERTY(Category = "Character Movement", EditAnywhere, BlueprintReadWrite)
	float WalkJumpVelocity;

	bool bSprint;
	
};

in your Defaultinput.ini add:

+ActionMappings=(ActionName="Sprint", Key=LeftShift)

Also, suggestions how to make the code better or more efficient are welcome!