I’ve just started to learn Unreal and reading the tutorial Components and Collisions I have found that they use the UPawnMovementComponent
to control their Pawn
.
Before reading this tutorial I have added the code to move the Pawn inside its C++ code:
#include "Paddle.h"
#include "Components/BoxComponent.h"
#include "Components/StaticMeshComponent.h"
// Sets default values
APaddle::APaddle()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
// Set this pawn to be controlled by the lowest-numbered player
AutoPossessPlayer = EAutoReceiveInput::Player0;
VisualComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("VisualComp"));
RootComponent = VisualComponent;
// Removed for brevety
CurrentVelocity.Z = 0.0f;
}
// Called when the game starts or when spawned
void APaddle::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void APaddle::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// Handle movement based on our "MoveZ" axis.
if (!CurrentVelocity.IsZero())
{
const FVector NewLocation = GetActorLocation() + (CurrentVelocity * DeltaTime);
SetActorLocation(NewLocation);
}
}
// Called to bind functionality to input
void APaddle::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
// Respond every frame to the values of our movement.
InputComponent->BindAxis(TEXT("MovePaddle"), this, &APaddle::Move_ZAxis);
}
void APaddle::Move_ZAxis(float AxisValue)
{
CurrentVelocity.Z = FMath::Clamp(AxisValue, -1.0f, 1.0f) * 100.0f;
}
A Tip from that tutorial says:
Pawn Movement Components have some powerful, built-in features to help with common physics functionality, and are a good way to share movement code between many Pawn types. Using Components to separate functionality is a good practice to reduce clutter as your project grows and your Pawns become more complex.
They say that using Pawn Movement Components
is a good way to share movement code between many Pawn but they have the same code than I inside their Pawn component:
// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.
#include "CollidingPawn.h"
#include "CollidingPawnMovementComponent.h"
#include "UObject/ConstructorHelpers.h"
#include "Particles/ParticleSystemComponent.h"
#include "Components/SphereComponent.h"
#include "Camera/CameraComponent.h"
#include "GameFramework/SpringArmComponent.h"
// Sets default values
ACollidingPawn::ACollidingPawn()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
// Removed for brevety
// Take control of the default player
AutoPossessPlayer = EAutoReceiveInput::Player0;
// Create an instance of our movement component, and tell it to update our root component.
OurMovementComponent = CreateDefaultSubobject<UCollidingPawnMovementComponent>(TEXT("CustomMovementComponent"));
OurMovementComponent->UpdatedComponent = RootComponent;
}
// Called when the game starts or when spawned
void ACollidingPawn::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void ACollidingPawn::Tick( float DeltaTime )
{
Super::Tick( DeltaTime );
}
// Called to bind functionality to input
void ACollidingPawn::SetupPlayerInputComponent(class UInputComponent* InInputComponent)
{
Super::SetupPlayerInputComponent(InInputComponent);
InInputComponent->BindAction("ParticleToggle", IE_Pressed, this, &ACollidingPawn::ParticleToggle);
InInputComponent->BindAxis("MoveForward", this, &ACollidingPawn::MoveForward);
InInputComponent->BindAxis("MoveRight", this, &ACollidingPawn::MoveRight);
InInputComponent->BindAxis("Turn", this, &ACollidingPawn::Turn);
}
UPawnMovementComponent* ACollidingPawn::GetMovementComponent() const
{
return OurMovementComponent;
}
void ACollidingPawn::MoveForward(float AxisValue)
{
if (OurMovementComponent && (OurMovementComponent->UpdatedComponent == RootComponent))
{
OurMovementComponent->AddInputVector(GetActorForwardVector() * AxisValue);
}
}
void ACollidingPawn::MoveRight(float AxisValue)
{
if (OurMovementComponent && (OurMovementComponent->UpdatedComponent == RootComponent))
{
OurMovementComponent->AddInputVector(GetActorRightVector() * AxisValue);
}
}
void ACollidingPawn::Turn(float AxisValue)
{
FRotator NewRotation = GetActorRotation();
NewRotation.Yaw += AxisValue;
SetActorRotation(NewRotation);
}
void ACollidingPawn::ParticleToggle()
{
if (OurParticleSystem && OurParticleSystem->Template)
{
OurParticleSystem->ToggleActive();
}
}
They have the a SetupPlayerInputComponent
method and three methods to move the Pawn inside the Pawn class. I don’t know how they are going to share move code between Pawn if the code is inside each Pawn.
How can I use UPawnMovementComponent
to control a Pawn with Keyboard sharing that code with other Pawns?