Clamp position when character's reach max distance apart so they are always in camera view
Clamp position when character's reach max distance apart so they are always in camera view
This commit is contained in:
parent
4d10d9cb32
commit
0942a3a1c6
@ -8,17 +8,20 @@
|
|||||||
#include "GameFramework/CharacterMovementComponent.h"
|
#include "GameFramework/CharacterMovementComponent.h"
|
||||||
#include "GameFramework/SpringArmComponent.h"
|
#include "GameFramework/SpringArmComponent.h"
|
||||||
#include "PaperFlipbookComponent.h"
|
#include "PaperFlipbookComponent.h"
|
||||||
|
#include "Componenets/KOFCharacterMovementComponent.h"
|
||||||
|
#include "GameModes/KOFDefaultGameMode.h"
|
||||||
|
|
||||||
DEFINE_LOG_CATEGORY_STATIC(SideScrollerCharacter, Log, All);
|
DEFINE_LOG_CATEGORY_STATIC(SideScrollerCharacter, Log, All);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// ASideScroller2DCharacter
|
// ASideScroller2DCharacter
|
||||||
|
|
||||||
AKOFBaseCharacter::AKOFBaseCharacter()
|
AKOFBaseCharacter::AKOFBaseCharacter(const FObjectInitializer& ObjectInitializer)
|
||||||
|
: Super(ObjectInitializer.SetDefaultSubobjectClass<UKOFCharacterMovementComponent>(ACharacter::CharacterMovementComponentName))
|
||||||
{
|
{
|
||||||
// Use only Yaw from the controller and ignore the rest of the rotation.
|
// Use only Yaw from the controller and ignore the rest of the rotation.
|
||||||
bUseControllerRotationPitch = false;
|
bUseControllerRotationPitch = false;
|
||||||
bUseControllerRotationYaw = true;
|
bUseControllerRotationYaw = false;
|
||||||
bUseControllerRotationRoll = false;
|
bUseControllerRotationRoll = false;
|
||||||
|
|
||||||
// Set the size of our collision capsule.
|
// Set the size of our collision capsule.
|
||||||
@ -29,7 +32,7 @@ AKOFBaseCharacter::AKOFBaseCharacter()
|
|||||||
|
|
||||||
// Configure character movement
|
// Configure character movement
|
||||||
GetCharacterMovement()->GravityScale = 2.0f;
|
GetCharacterMovement()->GravityScale = 2.0f;
|
||||||
GetCharacterMovement()->AirControl = 0.80f;
|
GetCharacterMovement()->AirControl = 0.0f;
|
||||||
GetCharacterMovement()->JumpZVelocity = 1000.f;
|
GetCharacterMovement()->JumpZVelocity = 1000.f;
|
||||||
GetCharacterMovement()->GroundFriction = 3.0f;
|
GetCharacterMovement()->GroundFriction = 3.0f;
|
||||||
GetCharacterMovement()->MaxWalkSpeed = 600.0f;
|
GetCharacterMovement()->MaxWalkSpeed = 600.0f;
|
||||||
@ -159,22 +162,5 @@ void AKOFBaseCharacter::UpdateCharacter()
|
|||||||
{
|
{
|
||||||
// Update animation to match the motion
|
// Update animation to match the motion
|
||||||
UpdateAnimation();
|
UpdateAnimation();
|
||||||
|
|
||||||
/*
|
|
||||||
// Now setup the rotation of the controller based on the direction we are travelling
|
|
||||||
const FVector PlayerVelocity = GetVelocity();
|
|
||||||
float TravelDirection = PlayerVelocity.Y;
|
|
||||||
// Set the rotation so that the character faces his direction of travel.
|
|
||||||
if (Controller != nullptr)
|
|
||||||
{
|
|
||||||
if (TravelDirection < 0.0f)
|
|
||||||
{
|
|
||||||
Controller->SetControlRotation(FRotator(0.0, -90.0f, 0.0f));
|
|
||||||
}
|
|
||||||
else if (TravelDirection > 0.0f)
|
|
||||||
{
|
|
||||||
Controller->SetControlRotation(FRotator(0.0f, 90.0f, 0.0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,76 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "Componenets/KOFCharacterMovementComponent.h"
|
||||||
|
|
||||||
|
#include "GameModes/KOFDefaultGameMode.h"
|
||||||
|
|
||||||
|
UKOFCharacterMovementComponent::UKOFCharacterMovementComponent()
|
||||||
|
{
|
||||||
|
PrimaryComponentTick.bCanEverTick = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UKOFCharacterMovementComponent::TickComponent(float DeltaTime, ELevelTick TickType,
|
||||||
|
FActorComponentTickFunction* ThisTickFunction)
|
||||||
|
{
|
||||||
|
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
||||||
|
|
||||||
|
AKOFBaseCharacter* Owner = Cast<AKOFBaseCharacter>(GetOwner());
|
||||||
|
if(!Owner)
|
||||||
|
{
|
||||||
|
UE_LOG(LogTemp, Error, TEXT("AKOFCharacterMovementComponent::PostPhysicsTickComponent - could not get the owner"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AKOFDefaultGameMode* GameMode = Cast<AKOFDefaultGameMode>(GetWorld()->GetAuthGameMode());
|
||||||
|
if(!GameMode)
|
||||||
|
{
|
||||||
|
UE_LOG(LogTemp, Error, TEXT("AKOFCharacterMovementComponent::PostPhysicsTickComponent - could not get the game mode"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AKOFBaseCharacter* Opponent = GameMode->GetCurrentOpponent(Owner->IsPossessedByPlayer1());
|
||||||
|
if(Opponent)
|
||||||
|
{
|
||||||
|
float HalfYDistance = GameMode->GetMaxAllowedDistanceFromOpponent() / 2.0f;
|
||||||
|
float YMidpoint = (Owner->GetActorLocation().Y + Opponent->GetActorLocation().Y) / 2.0f;
|
||||||
|
|
||||||
|
float AdjustedY = FMath::Clamp(Owner->GetActorLocation().Y, YMidpoint - HalfYDistance, YMidpoint + HalfYDistance);
|
||||||
|
|
||||||
|
FVector CurrentLoc = Owner->GetActorLocation();
|
||||||
|
Owner->SetActorLocation(FVector(CurrentLoc.X, AdjustedY, CurrentLoc.Z));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UKOFCharacterMovementComponent::PostPhysicsTickComponent(float DeltaTime,
|
||||||
|
FCharacterMovementComponentPostPhysicsTickFunction& ThisTickFunction)
|
||||||
|
{
|
||||||
|
Super::PostPhysicsTickComponent(DeltaTime, ThisTickFunction);
|
||||||
|
|
||||||
|
AKOFBaseCharacter* Owner = Cast<AKOFBaseCharacter>(GetOwner());
|
||||||
|
if(!Owner)
|
||||||
|
{
|
||||||
|
UE_LOG(LogTemp, Error, TEXT("AKOFCharacterMovementComponent::PostPhysicsTickComponent - could not get the owner"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AKOFDefaultGameMode* GameMode = Cast<AKOFDefaultGameMode>(GetWorld()->GetAuthGameMode());
|
||||||
|
if(!GameMode)
|
||||||
|
{
|
||||||
|
UE_LOG(LogTemp, Error, TEXT("AKOFCharacterMovementComponent::PostPhysicsTickComponent - could not get the game mode"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AKOFBaseCharacter* Opponent = GameMode->GetCurrentOpponent(Owner->IsPossessedByPlayer1());
|
||||||
|
if(Opponent)
|
||||||
|
{
|
||||||
|
float YDistance = FMath::Abs(Opponent->GetActorLocation().Y - Owner->GetActorLocation().Y);
|
||||||
|
float HalfYDistance = YDistance / 2.0f;
|
||||||
|
float YMidpoint = (Owner->GetActorLocation().Y + Opponent->GetActorLocation().Y) / 2.0f;
|
||||||
|
|
||||||
|
float AdjustedY = FMath::Clamp(Owner->GetActorLocation().Y, YMidpoint - HalfYDistance, YMidpoint + HalfYDistance);
|
||||||
|
|
||||||
|
FVector CurrentLoc = Owner->GetActorLocation();
|
||||||
|
Owner->SetActorLocation(FVector(CurrentLoc.X, AdjustedY, CurrentLoc.Z));
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,7 @@ AKOFDefaultGameMode::AKOFDefaultGameMode()
|
|||||||
{
|
{
|
||||||
NumCharactersPerTeam = 3;
|
NumCharactersPerTeam = 3;
|
||||||
|
|
||||||
MaxDistance = 700.0f;
|
MaxAllowedDistanceFromOpponent = 700.0f;
|
||||||
StartY = 250.0f;
|
StartY = 250.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,6 +18,7 @@ void AKOFDefaultGameMode::InitTeams()
|
|||||||
for (TSubclassOf<AKOFBaseCharacter> CharacterTemplate : P1TeamTemplate)
|
for (TSubclassOf<AKOFBaseCharacter> CharacterTemplate : P1TeamTemplate)
|
||||||
{
|
{
|
||||||
AKOFBaseCharacter* Temp = GetWorld()->SpawnActor<AKOFBaseCharacter>(CharacterTemplate, FVector(0.0f, -StartY, 204.6241f), FRotator(0.0f, 90.0f, 0.0f));
|
AKOFBaseCharacter* Temp = GetWorld()->SpawnActor<AKOFBaseCharacter>(CharacterTemplate, FVector(0.0f, -StartY, 204.6241f), FRotator(0.0f, 90.0f, 0.0f));
|
||||||
|
Temp->SetIsPossesedByPlayer1(true);
|
||||||
if(Temp)
|
if(Temp)
|
||||||
{
|
{
|
||||||
P1Team.Add(Temp);
|
P1Team.Add(Temp);
|
||||||
@ -27,7 +28,7 @@ void AKOFDefaultGameMode::InitTeams()
|
|||||||
for (TSubclassOf<AKOFBaseCharacter> CharacterTemplate : P2TeamTemplate)
|
for (TSubclassOf<AKOFBaseCharacter> CharacterTemplate : P2TeamTemplate)
|
||||||
{
|
{
|
||||||
AKOFBaseCharacter* Temp = GetWorld()->SpawnActor<AKOFBaseCharacter>(CharacterTemplate, FVector(0.0f, StartY, 204.6241f), FRotator(0.0f, -90.0f, 0.0f));
|
AKOFBaseCharacter* Temp = GetWorld()->SpawnActor<AKOFBaseCharacter>(CharacterTemplate, FVector(0.0f, StartY, 204.6241f), FRotator(0.0f, -90.0f, 0.0f));
|
||||||
Temp->AutoPossessPlayer = EAutoReceiveInput::Player1;
|
Temp->SetIsPossesedByPlayer1(false);
|
||||||
if(Temp)
|
if(Temp)
|
||||||
{
|
{
|
||||||
P2Team.Add(Temp);
|
P2Team.Add(Temp);
|
||||||
|
@ -51,6 +51,9 @@ protected:
|
|||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Animations)
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Animations)
|
||||||
class UPaperFlipbook* IdleAnimation;
|
class UPaperFlipbook* IdleAnimation;
|
||||||
|
|
||||||
|
UPROPERTY(BlueprintReadOnly)
|
||||||
|
bool bIsPossesedByPlayer1;
|
||||||
|
|
||||||
/** Called to choose the correct animation to play based on the character's movement state */
|
/** Called to choose the correct animation to play based on the character's movement state */
|
||||||
void UpdateAnimation();
|
void UpdateAnimation();
|
||||||
|
|
||||||
@ -64,7 +67,21 @@ protected:
|
|||||||
// End of APawn interface
|
// End of APawn interface
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AKOFBaseCharacter();
|
AKOFBaseCharacter(const FObjectInitializer& ObjectInitializer);
|
||||||
|
|
||||||
FORCEINLINE class UPaperFlipbookComponent* GetShadow() const { return Shadow; }
|
FORCEINLINE class UPaperFlipbookComponent* GetShadow() const { return Shadow; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not this player is possessed by player 1
|
||||||
|
*
|
||||||
|
* @returns true is possessed by player 1, false if possessed by player 2
|
||||||
|
*/
|
||||||
|
FORCEINLINE bool IsPossessedByPlayer1() const { return bIsPossesedByPlayer1; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets which player this character is possesed by.
|
||||||
|
*
|
||||||
|
* @param bIsPlayer1 true is possessed by player 1, false if possessed by player 2
|
||||||
|
*/
|
||||||
|
FORCEINLINE void SetIsPossesedByPlayer1(bool bIsPlayer1) { bIsPossesedByPlayer1 = bIsPlayer1; }
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "GameFramework/CharacterMovementComponent.h"
|
||||||
|
#include "KOFCharacterMovementComponent.generated.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
UCLASS()
|
||||||
|
class KOFFOREVER_API UKOFCharacterMovementComponent : public UCharacterMovementComponent
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
UKOFCharacterMovementComponent();
|
||||||
|
|
||||||
|
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
|
||||||
|
|
||||||
|
virtual void PostPhysicsTickComponent(float DeltaTime, FCharacterMovementComponentPostPhysicsTickFunction& ThisTickFunction) override;
|
||||||
|
};
|
@ -29,6 +29,10 @@ public:
|
|||||||
// this will need to change when we actually have real time character switching
|
// this will need to change when we actually have real time character switching
|
||||||
AKOFBaseCharacter* GetP2CurrentCharacter() { return P2Team.Num() > 0 ? P2Team[0] : nullptr; }
|
AKOFBaseCharacter* GetP2CurrentCharacter() { return P2Team.Num() > 0 ? P2Team[0] : nullptr; }
|
||||||
|
|
||||||
|
AKOFBaseCharacter* GetCurrentOpponent(bool bIsPlayer1) { return bIsPlayer1 ? GetP2CurrentCharacter() : GetP1CurrentCharacter(); }
|
||||||
|
|
||||||
|
FORCEINLINE float GetMaxAllowedDistanceFromOpponent() { return MaxAllowedDistanceFromOpponent; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Number of characters on a single player's team */
|
/** Number of characters on a single player's team */
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Settings|Team")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Settings|Team")
|
||||||
@ -36,7 +40,7 @@ protected:
|
|||||||
|
|
||||||
/** Max distance the currently controlled player characters can be from one another */
|
/** Max distance the currently controlled player characters can be from one another */
|
||||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Settings|Stage")
|
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Settings|Stage")
|
||||||
float MaxDistance;
|
float MaxAllowedDistanceFromOpponent;
|
||||||
|
|
||||||
/** Y offset from origin where character's will be spawned */
|
/** Y offset from origin where character's will be spawned */
|
||||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Settings|Stage")
|
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Settings|Stage")
|
||||||
|
Loading…
Reference in New Issue
Block a user