Add new BaseCharacter and RenderableCharacter classes

This commit is contained in:
Kevin Poretti 2022-01-24 21:15:00 -05:00
parent 3cec1a4e94
commit b2b6f339d8
15 changed files with 375 additions and 323 deletions

Binary file not shown.

BIN
KOFForever/Content/Characters/Terry/BP_TerryRender.uasset (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

View File

@ -4,7 +4,7 @@
#include "DrawDebugHelpers.h"
#include "Camera/CameraComponent.h"
#include "Character/KOFBaseCharacter.h"
#include "Character/KOFBaseCharacter_DEPRECATED.h"
#include "GameModes/KOFDefaultGameMode.h"
#include "Kismet/GameplayStatics.h"
@ -32,8 +32,8 @@ void AKOFDefaultCamera::Tick(float DeltaSeconds)
if(GameMode)
{
AKOFBaseCharacter* P1 = GameMode->GetP1CurrentCharacter();
AKOFBaseCharacter* P2 = GameMode->GetP2CurrentCharacter();
AKOFBaseCharacter_DEPRECATED* P1 = GameMode->GetP1CurrentCharacter();
AKOFBaseCharacter_DEPRECATED* P2 = GameMode->GetP2CurrentCharacter();
check(P1);
check(P2);
@ -58,8 +58,8 @@ void AKOFDefaultCamera::UpdateCamera()
if(GameMode)
{
AKOFBaseCharacter* P1 = GameMode->GetP1CurrentCharacter();
AKOFBaseCharacter* P2 = GameMode->GetP2CurrentCharacter();
AKOFBaseCharacter_DEPRECATED* P1 = GameMode->GetP1CurrentCharacter();
AKOFBaseCharacter_DEPRECATED* P2 = GameMode->GetP2CurrentCharacter();
FVector P1Loc = P1->GetActorLocation();
FVector P2Loc = P2->GetActorLocation();

View File

@ -1,165 +1,5 @@
// A fan game by poret. This game is not affiliated with SNK. This is a fan game which is not being sold or distributed for profit.
#include "Character/KOFBaseCharacter.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "PaperFlipbookComponent.h"
#include "Componenets/KOFCharacterMovementComponent.h"
#include "GameModes/KOFDefaultGameMode.h"
DEFINE_LOG_CATEGORY_STATIC(SideScrollerCharacter, Log, All);
//////////////////////////////////////////////////////////////////////////
// ASideScroller2DCharacter
AKOFBaseCharacter::AKOFBaseCharacter(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer.SetDefaultSubobjectClass<UKOFCharacterMovementComponent>(ACharacter::CharacterMovementComponentName))
{
// Use only Yaw from the controller and ignore the rest of the rotation.
bUseControllerRotationPitch = false;
bUseControllerRotationYaw = false;
bUseControllerRotationRoll = false;
// Set the size of our collision capsule.
GetCapsuleComponent()->SetCapsuleHalfHeight(96.0f);
GetCapsuleComponent()->SetCapsuleRadius(40.0f);
GetCharacterMovement()->bOrientRotationToMovement = false;
// Configure character movement
GetCharacterMovement()->GravityScale = 2.0f;
GetCharacterMovement()->AirControl = 0.0f;
GetCharacterMovement()->JumpZVelocity = 1000.f;
GetCharacterMovement()->GroundFriction = 3.0f;
GetCharacterMovement()->MaxWalkSpeed = 600.0f;
GetCharacterMovement()->MaxFlySpeed = 600.0f;
// Lock character motion onto the XZ plane, so the character can't move in or out of the screen
GetCharacterMovement()->bConstrainToPlane = true;
GetCharacterMovement()->SetPlaneConstraintNormal(FVector(1.0, 0.0f, 0.0f));
// Behave like a traditional 2D platformer character, with a flat bottom instead of a curved capsule bottom
// Note: This can cause a little floating when going up inclines; you can choose the tradeoff between better
// behavior on the edge of a ledge versus inclines by setting this to true or false
GetCharacterMovement()->bUseFlatBaseForFloorChecks = true;
// TextComponent = CreateDefaultSubobject<UTextRenderComponent>(TEXT("IncarGear"));
// TextComponent->SetRelativeScale3D(FVector(3.0f, 3.0f, 3.0f));
// TextComponent->SetRelativeLocation(FVector(35.0f, 5.0f, 20.0f));
// TextComponent->SetRelativeRotation(FRotator(0.0f, 90.0f, 0.0f));
// TextComponent->SetupAttachment(RootComponent);
// Enable replication on the Sprite component so animations show up when networked
GetSprite()->SetIsReplicated(true);
GetSprite()->SetRelativeLocation(FVector(0.0f, 0.0f, -96.0f));
bReplicates = true;
// Try to create the sprite component
Shadow = CreateOptionalDefaultSubobject<UPaperFlipbookComponent>(TEXT("Shadow"));
if (Shadow)
{
Shadow->AlwaysLoadOnClient = true;
Shadow->AlwaysLoadOnServer = true;
Shadow->bOwnerNoSee = false;
Shadow->bAffectDynamicIndirectLighting = true;
Shadow->PrimaryComponentTick.TickGroup = TG_PrePhysics;
Shadow->SetupAttachment(GetCapsuleComponent());
Shadow->SetRelativeLocation(FVector(0.0f, 0.0f, -96.0f));
Shadow->SetRelativeScale3D(FVector(1.0f, 1.0f, -0.3f));
Shadow->SetSpriteColor(FLinearColor::Black);
Shadow->SetTranslucentSortPriority(1000);
}
}
//////////////////////////////////////////////////////////////////////////
// Animation
void AKOFBaseCharacter::UpdateAnimation()
{
const FVector PlayerVelocity = GetVelocity();
const float PlayerSpeedSqr = PlayerVelocity.SizeSquared();
const float TravelDirection = PlayerVelocity.Y;
// Are we moving or standing still?
UPaperFlipbook* DesiredAnimation = IdleAnimation;
if(PlayerSpeedSqr > 0.0f)
{
if (TravelDirection > 0.0f)
{
DesiredAnimation = WalkFwdAnimation;
}
else if (TravelDirection < 0.0f)
{
DesiredAnimation = WalkBackAnimation;
}
}
if( GetSprite()->GetFlipbook() != DesiredAnimation )
{
GetSprite()->SetFlipbook(DesiredAnimation);
Shadow->SetFlipbook(DesiredAnimation);
}
}
void AKOFBaseCharacter::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
UpdateCharacter();
}
void AKOFBaseCharacter::BeginPlay()
{
Super::BeginPlay();
if(Controller)
{
Controller->SetControlRotation(FRotator(0.0f, -90.0f, 0.0));
}
}
void AKOFBaseCharacter::PostInitializeComponents()
{
Super::PostInitializeComponents();
if (!IsPendingKill())
{
if (Shadow)
{
// force animation tick after movement component updates
if (Shadow->PrimaryComponentTick.bCanEverTick && GetCharacterMovement())
{
Shadow->PrimaryComponentTick.AddPrerequisite(GetCharacterMovement(), GetCharacterMovement()->PrimaryComponentTick);
}
}
}
}
//////////////////////////////////////////////////////////////////////////
// Input
void AKOFBaseCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
{
// Note: the 'Jump' action and the 'MoveRight' axis are bound to actual keys/buttons/sticks in DefaultInput.ini (editable from Project Settings..Input)
PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);
PlayerInputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping);
PlayerInputComponent->BindAxis("MoveRight", this, &AKOFBaseCharacter::MoveRight);
}
void AKOFBaseCharacter::MoveRight(float Value)
{
/*UpdateChar();*/
// Apply the input to the character motion
AddMovementInput(FVector(0.0f, 1.0f, 0.0f), Value);
}
void AKOFBaseCharacter::UpdateCharacter()
{
// Update animation to match the motion
UpdateAnimation();
}

View File

@ -0,0 +1,165 @@
// A fan game by poret. This game is not affiliated with SNK. This is a fan game which is not being sold or distributed for profit.
#include "Character/KOFBaseCharacter_DEPRECATED.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "PaperFlipbookComponent.h"
#include "Componenets/KOFCharacterMovementComponent.h"
#include "GameModes/KOFDefaultGameMode.h"
DEFINE_LOG_CATEGORY_STATIC(SideScrollerCharacter, Log, All);
//////////////////////////////////////////////////////////////////////////
// ASideScroller2DCharacter
AKOFBaseCharacter_DEPRECATED::AKOFBaseCharacter_DEPRECATED(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer.SetDefaultSubobjectClass<UKOFCharacterMovementComponent>(ACharacter::CharacterMovementComponentName))
{
// Use only Yaw from the controller and ignore the rest of the rotation.
bUseControllerRotationPitch = false;
bUseControllerRotationYaw = false;
bUseControllerRotationRoll = false;
// Set the size of our collision capsule.
GetCapsuleComponent()->SetCapsuleHalfHeight(96.0f);
GetCapsuleComponent()->SetCapsuleRadius(40.0f);
GetCharacterMovement()->bOrientRotationToMovement = false;
// Configure character movement
GetCharacterMovement()->GravityScale = 2.0f;
GetCharacterMovement()->AirControl = 0.0f;
GetCharacterMovement()->JumpZVelocity = 1000.f;
GetCharacterMovement()->GroundFriction = 3.0f;
GetCharacterMovement()->MaxWalkSpeed = 600.0f;
GetCharacterMovement()->MaxFlySpeed = 600.0f;
// Lock character motion onto the XZ plane, so the character can't move in or out of the screen
GetCharacterMovement()->bConstrainToPlane = true;
GetCharacterMovement()->SetPlaneConstraintNormal(FVector(1.0, 0.0f, 0.0f));
// Behave like a traditional 2D platformer character, with a flat bottom instead of a curved capsule bottom
// Note: This can cause a little floating when going up inclines; you can choose the tradeoff between better
// behavior on the edge of a ledge versus inclines by setting this to true or false
GetCharacterMovement()->bUseFlatBaseForFloorChecks = true;
// TextComponent = CreateDefaultSubobject<UTextRenderComponent>(TEXT("IncarGear"));
// TextComponent->SetRelativeScale3D(FVector(3.0f, 3.0f, 3.0f));
// TextComponent->SetRelativeLocation(FVector(35.0f, 5.0f, 20.0f));
// TextComponent->SetRelativeRotation(FRotator(0.0f, 90.0f, 0.0f));
// TextComponent->SetupAttachment(RootComponent);
// Enable replication on the Sprite component so animations show up when networked
GetSprite()->SetIsReplicated(true);
GetSprite()->SetRelativeLocation(FVector(0.0f, 0.0f, -96.0f));
bReplicates = true;
// Try to create the sprite component
Shadow = CreateOptionalDefaultSubobject<UPaperFlipbookComponent>(TEXT("Shadow"));
if (Shadow)
{
Shadow->AlwaysLoadOnClient = true;
Shadow->AlwaysLoadOnServer = true;
Shadow->bOwnerNoSee = false;
Shadow->bAffectDynamicIndirectLighting = true;
Shadow->PrimaryComponentTick.TickGroup = TG_PrePhysics;
Shadow->SetupAttachment(GetCapsuleComponent());
Shadow->SetRelativeLocation(FVector(0.0f, 0.0f, -96.0f));
Shadow->SetRelativeScale3D(FVector(1.0f, 1.0f, -0.3f));
Shadow->SetSpriteColor(FLinearColor::Black);
Shadow->SetTranslucentSortPriority(1000);
}
}
//////////////////////////////////////////////////////////////////////////
// Animation
void AKOFBaseCharacter_DEPRECATED::UpdateAnimation()
{
const FVector PlayerVelocity = GetVelocity();
const float PlayerSpeedSqr = PlayerVelocity.SizeSquared();
const float TravelDirection = PlayerVelocity.Y;
// Are we moving or standing still?
UPaperFlipbook* DesiredAnimation = IdleAnimation;
if(PlayerSpeedSqr > 0.0f)
{
if (TravelDirection > 0.0f)
{
DesiredAnimation = WalkFwdAnimation;
}
else if (TravelDirection < 0.0f)
{
DesiredAnimation = WalkBackAnimation;
}
}
if( GetSprite()->GetFlipbook() != DesiredAnimation )
{
GetSprite()->SetFlipbook(DesiredAnimation);
Shadow->SetFlipbook(DesiredAnimation);
}
}
void AKOFBaseCharacter_DEPRECATED::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
UpdateCharacter();
}
void AKOFBaseCharacter_DEPRECATED::BeginPlay()
{
Super::BeginPlay();
if(Controller)
{
Controller->SetControlRotation(FRotator(0.0f, -90.0f, 0.0));
}
}
void AKOFBaseCharacter_DEPRECATED::PostInitializeComponents()
{
Super::PostInitializeComponents();
if (!IsPendingKill())
{
if (Shadow)
{
// force animation tick after movement component updates
if (Shadow->PrimaryComponentTick.bCanEverTick && GetCharacterMovement())
{
Shadow->PrimaryComponentTick.AddPrerequisite(GetCharacterMovement(), GetCharacterMovement()->PrimaryComponentTick);
}
}
}
}
//////////////////////////////////////////////////////////////////////////
// Input
void AKOFBaseCharacter_DEPRECATED::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
{
// Note: the 'Jump' action and the 'MoveRight' axis are bound to actual keys/buttons/sticks in DefaultInput.ini (editable from Project Settings..Input)
PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);
PlayerInputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping);
PlayerInputComponent->BindAxis("MoveRight", this, &AKOFBaseCharacter_DEPRECATED::MoveRight);
}
void AKOFBaseCharacter_DEPRECATED::MoveRight(float Value)
{
/*UpdateChar();*/
// Apply the input to the character motion
AddMovementInput(FVector(0.0f, 1.0f, 0.0f), Value);
}
void AKOFBaseCharacter_DEPRECATED::UpdateCharacter()
{
// Update animation to match the motion
UpdateAnimation();
}

View File

@ -0,0 +1,51 @@
// A fan game by poret. This game is not affiliated with SNK. This is a fan game which is not being sold or distributed for profit.
#include "Character/KOFRenderableCharacter.h"
#include "PaperFlipbookComponent.h"
// Sets default values
AKOFRenderableCharacter::AKOFRenderableCharacter()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
Sprite = CreateOptionalDefaultSubobject<UPaperFlipbookComponent>(TEXT("Sprite"));
if (Sprite)
{
Sprite->AlwaysLoadOnClient = true;
Sprite->AlwaysLoadOnServer = true;
Sprite->bOwnerNoSee = false;
Sprite->bAffectDynamicIndirectLighting = true;
Sprite->SetupAttachment(RootComponent);
}
// Try to create the sprite component
Shadow = CreateOptionalDefaultSubobject<UPaperFlipbookComponent>(TEXT("Shadow"));
if (Shadow)
{
Shadow->AlwaysLoadOnClient = true;
Shadow->AlwaysLoadOnServer = true;
Shadow->bOwnerNoSee = false;
Shadow->bAffectDynamicIndirectLighting = true;
Shadow->SetupAttachment(Sprite);
Shadow->SetRelativeScale3D(FVector(1.0f, 1.0f, -0.3f));
Shadow->SetSpriteColor(FLinearColor::Black);
}
}
// Called when the game starts or when spawned
void AKOFRenderableCharacter::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AKOFRenderableCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}

View File

@ -14,7 +14,7 @@ void UKOFCharacterMovementComponent::TickComponent(float DeltaTime, ELevelTick T
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
AKOFBaseCharacter* Owner = Cast<AKOFBaseCharacter>(GetOwner());
AKOFBaseCharacter_DEPRECATED* Owner = Cast<AKOFBaseCharacter_DEPRECATED>(GetOwner());
if(!Owner)
{
UE_LOG(LogTemp, Error, TEXT("AKOFCharacterMovementComponent::PostPhysicsTickComponent - could not get the owner"));
@ -28,7 +28,7 @@ void UKOFCharacterMovementComponent::TickComponent(float DeltaTime, ELevelTick T
return;
}
AKOFBaseCharacter* Opponent = GameMode->GetCurrentOpponent(Owner->IsPossessedByPlayer1());
AKOFBaseCharacter_DEPRECATED* Opponent = GameMode->GetCurrentOpponent(Owner->IsPossessedByPlayer1());
if(Opponent)
{
float HalfYDistance = GameMode->GetMaxAllowedDistanceFromOpponent() / 2.0f;

View File

@ -15,9 +15,9 @@ AKOFDefaultGameMode::AKOFDefaultGameMode()
void AKOFDefaultGameMode::InitTeams()
{
for (TSubclassOf<AKOFBaseCharacter> CharacterTemplate : P1TeamTemplate)
for (TSubclassOf<AKOFBaseCharacter_DEPRECATED> CharacterTemplate : P1TeamTemplate)
{
AKOFBaseCharacter* Temp = GetWorld()->SpawnActor<AKOFBaseCharacter>(CharacterTemplate, FVector(0.0f, -StartY, 204.6241f), FRotator(0.0f, 90.0f, 0.0f));
AKOFBaseCharacter_DEPRECATED* Temp = GetWorld()->SpawnActor<AKOFBaseCharacter_DEPRECATED>(CharacterTemplate, FVector(0.0f, -StartY, 204.6241f), FRotator(0.0f, 90.0f, 0.0f));
Temp->SetIsPossesedByPlayer1(true);
if(Temp)
{
@ -25,9 +25,9 @@ void AKOFDefaultGameMode::InitTeams()
}
}
for (TSubclassOf<AKOFBaseCharacter> CharacterTemplate : P2TeamTemplate)
for (TSubclassOf<AKOFBaseCharacter_DEPRECATED> CharacterTemplate : P2TeamTemplate)
{
AKOFBaseCharacter* Temp = GetWorld()->SpawnActor<AKOFBaseCharacter>(CharacterTemplate, FVector(0.0f, StartY, 204.6241f), FRotator(0.0f, -90.0f, 0.0f));
AKOFBaseCharacter_DEPRECATED* Temp = GetWorld()->SpawnActor<AKOFBaseCharacter_DEPRECATED>(CharacterTemplate, FVector(0.0f, StartY, 204.6241f), FRotator(0.0f, -90.0f, 0.0f));
Temp->SetIsPossesedByPlayer1(false);
if(Temp)
{
@ -46,7 +46,7 @@ void AKOFDefaultGameMode::StartPlay()
APlayerController* PC1 = UGameplayStatics::GetPlayerController(GetWorld(), 0);
if(PC1)
{
AKOFBaseCharacter* P1 = GetP1CurrentCharacter();
AKOFBaseCharacter_DEPRECATED* P1 = GetP1CurrentCharacter();
if(P1)
{
PC1->Possess(P1);
@ -56,7 +56,7 @@ void AKOFDefaultGameMode::StartPlay()
APlayerController* PC2 = UGameplayStatics::GetPlayerController(GetWorld(), 1);
if(PC2)
{
AKOFBaseCharacter* P2 = GetP1CurrentCharacter();
AKOFBaseCharacter_DEPRECATED* P2 = GetP1CurrentCharacter();
if(P2)
{
PC2->Possess(P2);

View File

@ -1,22 +0,0 @@
// A fan game by poret. This game is not affiliated with SNK. This is a fan game which is not being sold or distributed for profit.
#include "GameModes/KOFTeam.h"
#include "Character/KOFBaseCharacter.h"
AKOFBaseCharacter* UKOFTeam::GetCurrentCharacter()
{
return Characters.Num() > 0 ? Characters[0] : nullptr;
}
void UKOFTeam::InitTeam()
{
for (TSubclassOf<AKOFBaseCharacter> CharacterTemplate : CharacterTemplates)
{
AKOFBaseCharacter* Temp = NewObject<AKOFBaseCharacter>(CharacterTemplate);
if(Temp)
{
Characters.Add(Temp);
}
}
}

View File

@ -3,85 +3,15 @@
#pragma once
#include "CoreMinimal.h"
#include "PaperCharacter.h"
#include "UObject/NoExportTypes.h"
#include "KOFBaseCharacter.generated.h"
class UTextRenderComponent;
/**
* This class is the default character for SideScroller2D, and it is responsible for all
* physical interaction between the player and the world.
*
* The capsule component (inherited from ACharacter) handles collision with the world
* The CharacterMovementComponent (inherited from ACharacter) handles movement of the collision capsule
* The Sprite component (inherited from APaperCharacter) handles the visuals
*
*/
UCLASS()
class KOFFOREVER_API AKOFBaseCharacter : public APaperCharacter
UCLASS(Blueprintable, meta=(ShortTooltip="Base class responsible for handling all character logic."))
class KOFFOREVER_API UKOFBaseCharacter : public UObject
{
GENERATED_BODY()
UTextRenderComponent* TextComponent;
virtual void Tick(float DeltaSeconds) override;
virtual void BeginPlay() override;
virtual void PostInitializeComponents() override;
protected:
/**
* Secondary sprite that is mirrored across the ground axis and set to black to give the effect of a
* character's shadow
*/
UPROPERTY(Category = Character, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
class UPaperFlipbookComponent* Shadow;
// The animation to play while running around
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Animations)
class UPaperFlipbook* RunningAnimation;
// The animation to play while running around
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Animations)
class UPaperFlipbook* WalkFwdAnimation;
// The animation to play while running around
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Animations)
class UPaperFlipbook* WalkBackAnimation;
// The animation to play while idle (standing still)
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Animations)
class UPaperFlipbook* IdleAnimation;
UPROPERTY(BlueprintReadOnly)
bool bIsPossesedByPlayer1;
/** Called to choose the correct animation to play based on the character's movement state */
void UpdateAnimation();
/** Called for side to side input */
void MoveRight(float Value);
void UpdateCharacter();
// APawn interface
virtual void SetupPlayerInputComponent(class UInputComponent* InputComponent) override;
// End of APawn interface
public:
AKOFBaseCharacter(const FObjectInitializer& ObjectInitializer);
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; }
};

View File

@ -0,0 +1,87 @@
// A fan game by poret. This game is not affiliated with SNK. This is a fan game which is not being sold or distributed for profit.
#pragma once
#include "CoreMinimal.h"
#include "PaperCharacter.h"
#include "KOFBaseCharacter_DEPRECATED.generated.h"
class UTextRenderComponent;
/**
* This class is the default character for SideScroller2D, and it is responsible for all
* physical interaction between the player and the world.
*
* The capsule component (inherited from ACharacter) handles collision with the world
* The CharacterMovementComponent (inherited from ACharacter) handles movement of the collision capsule
* The Sprite component (inherited from APaperCharacter) handles the visuals
*/
UCLASS()
class KOFFOREVER_API AKOFBaseCharacter_DEPRECATED : public APaperCharacter
{
GENERATED_BODY()
UTextRenderComponent* TextComponent;
virtual void Tick(float DeltaSeconds) override;
virtual void BeginPlay() override;
virtual void PostInitializeComponents() override;
protected:
/**
* Secondary sprite that is mirrored across the ground axis and set to black to give the effect of a
* character's shadow
*/
UPROPERTY(Category = Character, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
class UPaperFlipbookComponent* Shadow;
// The animation to play while running around
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Animations)
class UPaperFlipbook* RunningAnimation;
// The animation to play while running around
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Animations)
class UPaperFlipbook* WalkFwdAnimation;
// The animation to play while running around
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Animations)
class UPaperFlipbook* WalkBackAnimation;
// The animation to play while idle (standing still)
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Animations)
class UPaperFlipbook* IdleAnimation;
UPROPERTY(BlueprintReadOnly)
bool bIsPossesedByPlayer1;
/** Called to choose the correct animation to play based on the character's movement state */
void UpdateAnimation();
/** Called for side to side input */
void MoveRight(float Value);
void UpdateCharacter();
// APawn interface
virtual void SetupPlayerInputComponent(class UInputComponent* InputComponent) override;
// End of APawn interface
public:
AKOFBaseCharacter_DEPRECATED(const FObjectInitializer& ObjectInitializer);
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; }
};

View File

@ -0,0 +1,37 @@
// A fan game by poret. This game is not affiliated with SNK. This is a fan game which is not being sold or distributed for profit.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "KOFRenderableCharacter.generated.h"
UCLASS()
class KOFFOREVER_API AKOFRenderableCharacter : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AKOFRenderableCharacter();
protected:
/** The main flipbook representing the character */
UPROPERTY(Category = Character, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
class UPaperFlipbookComponent* Sprite;
/**
* Secondary sprite that is mirrored across the ground axis and set to black to give the effect of a
* character's shadow
*/
UPROPERTY(Category = Character, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
class UPaperFlipbookComponent* Shadow;
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
};

View File

@ -3,8 +3,7 @@
#pragma once
#include "CoreMinimal.h"
#include "KOFTeam.h"
#include "Character/KOFBaseCharacter.h"
#include "Character/KOFBaseCharacter_DEPRECATED.h"
#include "GameFramework/GameModeBase.h"
#include "KOFDefaultGameMode.generated.h"
@ -19,17 +18,17 @@ class KOFFOREVER_API AKOFDefaultGameMode : public AGameModeBase
public:
AKOFDefaultGameMode();
TArray<AKOFBaseCharacter*>& GetP1Team() { return P1Team; }
TArray<AKOFBaseCharacter_DEPRECATED*>& GetP1Team() { return P1Team; }
TArray<AKOFBaseCharacter*>& GetP2Team() { return P2Team; }
TArray<AKOFBaseCharacter_DEPRECATED*>& GetP2Team() { return P2Team; }
// this will need to change when we actually have real time character switching
AKOFBaseCharacter* GetP1CurrentCharacter() { return P1Team.Num() > 0 ? P1Team[0] : nullptr; }
AKOFBaseCharacter_DEPRECATED* GetP1CurrentCharacter() { return P1Team.Num() > 0 ? P1Team[0] : nullptr; }
// this will need to change when we actually have real time character switching
AKOFBaseCharacter* GetP2CurrentCharacter() { return P2Team.Num() > 0 ? P2Team[0] : nullptr; }
AKOFBaseCharacter_DEPRECATED* GetP2CurrentCharacter() { return P2Team.Num() > 0 ? P2Team[0] : nullptr; }
AKOFBaseCharacter* GetCurrentOpponent(bool bIsPlayer1) { return bIsPlayer1 ? GetP2CurrentCharacter() : GetP1CurrentCharacter(); }
AKOFBaseCharacter_DEPRECATED* GetCurrentOpponent(bool bIsPlayer1) { return bIsPlayer1 ? GetP2CurrentCharacter() : GetP1CurrentCharacter(); }
FORCEINLINE float GetMaxAllowedDistanceFromOpponent() { return MaxAllowedDistanceFromOpponent; }
@ -52,18 +51,18 @@ protected:
float StartY;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Settings|Team")
TArray<TSubclassOf<AKOFBaseCharacter>> P1TeamTemplate;
TArray<TSubclassOf<AKOFBaseCharacter_DEPRECATED>> P1TeamTemplate;
/** List of references to the player's team members */
UPROPERTY(BlueprintReadOnly)
TArray<AKOFBaseCharacter*> P1Team;
TArray<AKOFBaseCharacter_DEPRECATED*> P1Team;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Settings|Team")
TArray<TSubclassOf<AKOFBaseCharacter>> P2TeamTemplate;
TArray<TSubclassOf<AKOFBaseCharacter_DEPRECATED>> P2TeamTemplate;
/** List of references to the player's team members */
UPROPERTY(BlueprintReadOnly)
TArray<AKOFBaseCharacter*> P2Team;
TArray<AKOFBaseCharacter_DEPRECATED*> P2Team;
void InitTeams();

View File

@ -1,38 +0,0 @@
// A fan game by poret. This game is not affiliated with SNK. This is a fan game which is not being sold or distributed for profit.
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "KOFTeam.generated.h"
class AKOFBaseCharacter;
/**
*
*/
UCLASS(BlueprintType, Blueprintable)
class KOFFOREVER_API UKOFTeam : public UObject
{
GENERATED_BODY()
public:
/**
* Returns the character on this team that is currently on stage being controlled by the player
*/
AKOFBaseCharacter* GetCurrentCharacter();
void InitTeam();
protected:
/**
* List of character templates to spawn the player's team when the match begins.
*
* This will eventually get set by the player's choices in the character select menu
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Characters")
TArray<TSubclassOf<AKOFBaseCharacter>> CharacterTemplates;
/** List of references to the player's team members */
UPROPERTY(BlueprintReadOnly, Category="Characters")
TArray<AKOFBaseCharacter*> Characters;
};