Create new character class

This commit is contained in:
Kevin Poretti 2022-03-11 20:45:14 -05:00
parent dba265ac03
commit 2c7bf0fb53
15 changed files with 466 additions and 23 deletions

Binary file not shown.

BIN
SwordNGun/Content/Characters/Protagonist/BP_NewProtag.uasset (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
SwordNGun/Content/Maps/MovementTest.umap (Stored with Git LFS)

Binary file not shown.

View File

@ -0,0 +1,265 @@
// Project Sword & Gun Copyright © 2021 Kevin Poretti
#include "Characters/SNGCharacterBase_DEPRECATED.h"
#include "Components/CapsuleComponent.h"
#include "GameFramework/PawnMovementComponent.h"
#include "Kismet/KismetMathLibrary.h"
#include "SwordNGun/SwordNGun.h"
// Sets default values
ASNGCharacterBase_DEPRECATED::ASNGCharacterBase_DEPRECATED(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer.SetDefaultSubobjectClass<USNGCharacterMovementComponent>(ACharacter::CharacterMovementComponentName))
{
// By default calls Tick() every frame.
PrimaryActorTick.bCanEverTick = true;
StateMachineComponent = CreateDefaultSubobject<USNGStateMachineComponent>(TEXT("StateMachineComponent"));
HealthComponent = CreateDefaultSubobject<USNGHealthComponent>(TEXT("HealthComponent"));
GetCapsuleComponent()->SetCollisionResponseToChannel(COLLISION_RANGED_WEAPON, ECR_Ignore);
GetCapsuleComponent()->SetCollisionResponseToChannel(COLLISION_MELEE_WEAPON, ECR_Ignore);
EnableAllActions();
AController* MyController = GetController();
if(MyController)
{
GetController()->SetIgnoreMoveInput(false);
}
}
void ASNGCharacterBase_DEPRECATED::SetupRotateTowardsTarget(FRotator TargetRotation, float DegreesPerSecond, float MaxRotation)
{
RotateTimeElapsed = 0.0f;
InitialRot = GetActorRotation();
this->TargetRot = TargetRotation;
DegPerSecond = DegreesPerSecond;
this->MaxRot = MaxRotation;
RotateTime = FMath::Min(FMath::Abs(TargetRotation.Yaw - InitialRot.Yaw), MaxRotation) / DegreesPerSecond;
}
void ASNGCharacterBase_DEPRECATED::RotateTowardsTarget(float DeltaTime)
{
if(RotateTimeElapsed < RotateTime)
{
SetActorRotation(UKismetMathLibrary::RInterpTo_Constant(GetActorRotation(), TargetRot,
DeltaTime, DegPerSecond));
RotateTimeElapsed += DeltaTime;
}
}
void ASNGCharacterBase_DEPRECATED::SetIgnoreMovementInput(bool IsIgnored)
{
AController* MyController = GetController();
if(MyController)
{
GetController()->SetIgnoreMoveInput(IsIgnored);
}
}
void ASNGCharacterBase_DEPRECATED::DisableAllActions()
{
bCanMove = false;
bCanJump = false;
bCanDodge = false;
bCanAttack = false;
}
void ASNGCharacterBase_DEPRECATED::EnableAllActions()
{
bCanMove = true;
bCanJump = true;
bCanDodge = true;
bCanAttack = true;
}
void ASNGCharacterBase_DEPRECATED::SetCanMove(bool CanMove)
{
bCanMove = CanMove;
}
bool ASNGCharacterBase_DEPRECATED::CanMove()
{
return bCanMove;
}
void ASNGCharacterBase_DEPRECATED::SetCanCharacterJump(bool CanJump)
{
bCanJump = CanJump;
}
bool ASNGCharacterBase_DEPRECATED::CanCharacterJump()
{
return bCanJump;
}
void ASNGCharacterBase_DEPRECATED::SetCanAttack(bool CanAttack)
{
bCanAttack = CanAttack;
}
bool ASNGCharacterBase_DEPRECATED::CanAttack()
{
return bCanAttack;
}
void ASNGCharacterBase_DEPRECATED::SetCanDodge(bool CanDodge)
{
bCanDodge = CanDodge;
}
bool ASNGCharacterBase_DEPRECATED::CanDodge()
{
return bCanDodge;
}
void ASNGCharacterBase_DEPRECATED::ApplyHitStop(float HitStopTime, float HitSlowTime)
{
CurrHitStopTime = HitStopTime;
CurrHitSlowTime = HitSlowTime;
bIsInHitStop = true;
}
void ASNGCharacterBase_DEPRECATED::PushEvent_Implementation(FSNGEvent Event)
{
if(StateMachineComponent)
{
StateMachineComponent->PushEvent(Event);
}
}
ASNGWeaponBase* ASNGCharacterBase_DEPRECATED::GetCurrentWeapon_Implementation()
{
return nullptr;
}
void ASNGCharacterBase_DEPRECATED::ReceiveHit(FSNGHitData const& HitData, AController* EventInstigator, AActor* DamageCauser)
{
AActor* Causer = EventInstigator->GetPawn();
if(HitData.HitstopApplicationType == ESNGHitstopApplicationType::Both ||
HitData.HitstopApplicationType == ESNGHitstopApplicationType::ReceiverOnly)
{
ApplyHitStop(HitData.StopTime, HitData.SlowTime);
}
FVector AdjustedLaunchDir;
switch (HitData.LaunchDirectionType)
{
case ESNGLaunchDirectionType::UseCauserRotation:
{
FRotator CauserRotationYaw(0.0f, Causer->GetActorRotation().Yaw, 0.0f);
AdjustedLaunchDir = CauserRotationYaw.RotateVector(HitData.LaunchDirection);
}
break;
case ESNGLaunchDirectionType::UseLookAtRotation:
{
FRotator LookAtRotation = UKismetMathLibrary::FindLookAtRotation(Causer->GetActorLocation(), GetActorLocation());
FRotator LookAtRotationYaw(0.0f, LookAtRotation.Yaw, 0.0f);
AdjustedLaunchDir = LookAtRotationYaw.RotateVector(HitData.LaunchDirection);
}
break;
default:
{
AdjustedLaunchDir = HitData.LaunchDirection;
}
break;
}
switch (HitData.LaunchType)
{
case ESNGLaunchType::OnlyInAir:
{
bool IsInAir = GetMovementComponent()->IsFalling();
if(IsInAir)
{
AdjustedLaunchDir *= HitData.LaunchForce;
LaunchCharacter(AdjustedLaunchDir, true, true);
}
else
{
AdjustedLaunchDir = FVector(AdjustedLaunchDir.X, AdjustedLaunchDir.Y, 0.0f);
LaunchCharacter(AdjustedLaunchDir, true, true);
}
}
break;
case ESNGLaunchType::Always:
{
AdjustedLaunchDir *= HitData.LaunchForce;
LaunchCharacter(AdjustedLaunchDir, true, true);
}
break;
default:
{
}
break;
}
}
float ASNGCharacterBase_DEPRECATED::TakeDamage(float Damage, FDamageEvent const& DamageEvent, AController* EventInstigator,
AActor* DamageCauser)
{
Super::TakeDamage(Damage, DamageEvent, EventInstigator, DamageCauser);
if(HealthComponent)
{
HealthComponent->SubtractHealth(Damage);
}
if (DamageEvent.IsOfType(FSNGDamageEvent::ClassID))
{
// point damage event, pass off to helper function
FSNGDamageEvent* const MyDamageEvent = (FSNGDamageEvent*) &DamageEvent;
ReceiveHit(MyDamageEvent->HitData, EventInstigator, DamageCauser);
FSNGEvent Event;
Event.EventType = ESNGEventType::Damage;
Event.DamageData.HitData = MyDamageEvent->HitData;
Event.DamageData.EventInstigator = EventInstigator;
Event.DamageData.DamageCauser = DamageCauser;
Event.DamageData.SurfaceType = MyDamageEvent->SurfaceType;
Event.DamageData.ImpactPoint = MyDamageEvent->ImpactPoint;
PushEvent(Event);
}
return Damage;
}
void ASNGCharacterBase_DEPRECATED::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
RotateTowardsTarget(DeltaSeconds);
if(bIsInHitStop)
{
CurrHitStopTime = FMath::Clamp(CurrHitStopTime - GetWorld()->GetDeltaSeconds(), 0.0f, CurrHitStopTime);
if(CurrHitStopTime > 0.0f)
{
CustomTimeDilation = 0.0f;
}
else
{
CustomTimeDilation = 0.01;
CurrHitSlowTime = FMath::Clamp(CurrHitSlowTime - GetWorld()->GetDeltaSeconds(), 0.0f, CurrHitSlowTime);
if(CurrHitSlowTime == 0.0f)
{
CustomTimeDilation = 1.0f;
bIsInHitStop = false;
}
}
}
}
void ASNGCharacterBase_DEPRECATED::PostInitializeComponents()
{
Super::PostInitializeComponents();
SNGCharacterMovementComponent = Cast<USNGCharacterMovementComponent>(Super::GetMovementComponent());
}

View File

@ -5,7 +5,7 @@
USNGCharacterMovementComponent::USNGCharacterMovementComponent() USNGCharacterMovementComponent::USNGCharacterMovementComponent()
{ {
// Set defaults dealign with grounded movement // Set defaults dealing with grounded movement
DefaultGravityScale = 1.0f; DefaultGravityScale = 1.0f;
DefaultMaxWalkSpeed = 475.0f; DefaultMaxWalkSpeed = 475.0f;
FiringMaxWalkSpeed = 300.0f; FiringMaxWalkSpeed = 300.0f;
@ -13,7 +13,7 @@ USNGCharacterMovementComponent::USNGCharacterMovementComponent()
SprintingMaxWalkSpeed = 600.0f; SprintingMaxWalkSpeed = 600.0f;
// Set defaults dealing with jumping and being airborne // Set defaults dealing with jumping and being airborne
JumpForce = 1000.0f; DefaultJumpForce = 1000.0f;
DefaultAirFriction = 150.0f; DefaultAirFriction = 150.0f;
DefaultAirControl = 0.35; DefaultAirControl = 0.35;
@ -36,23 +36,28 @@ void USNGCharacterMovementComponent::RestoreMovementDefaults()
MaxWalkSpeed = DefaultMaxWalkSpeed; MaxWalkSpeed = DefaultMaxWalkSpeed;
BrakingDecelerationFalling = DefaultAirFriction; BrakingDecelerationFalling = DefaultAirFriction;
AirControl = DefaultAirControl; AirControl = DefaultAirControl;
JumpZVelocity = DefaultJumpForce;
} }
void USNGCharacterMovementComponent::StartJump() void USNGCharacterMovementComponent::StartJump()
{ {
/*
JumpTimer = MaxJumpTime; JumpTimer = MaxJumpTime;
Velocity = FVector(Velocity.X * LateralVelocityDampening, Velocity.Y * LateralVelocityDampening, 0.0f); Velocity = FVector(Velocity.X * LateralVelocityDampening, Velocity.Y * LateralVelocityDampening, 0.0f);
*/
} }
void USNGCharacterMovementComponent::AddJumpForce() void USNGCharacterMovementComponent::AddJumpForce()
{ {
/*
if(JumpTimer > 0.0f) if(JumpTimer > 0.0f)
{ {
Velocity = FVector(Velocity.X, Velocity.Y, Velocity.Z + (JumpForce * GetWorld()->DeltaTimeSeconds)); Velocity = FVector(Velocity.X, Velocity.Y, Velocity.Z + (JumpForce * GetWorld()->DeltaTimeSeconds));
JumpTimer = FMath::Max(JumpTimer - GetWorld()->DeltaTimeSeconds, 0.0f); JumpTimer = FMath::Max(JumpTimer - GetWorld()->DeltaTimeSeconds, 0.0f);
} }
*/
} }
void USNGCharacterMovementComponent::BeginPlay() void USNGCharacterMovementComponent::BeginPlay()
@ -61,9 +66,6 @@ void USNGCharacterMovementComponent::BeginPlay()
// set character movement parameters to defaults // set character movement parameters to defaults
RestoreMovementDefaults(); RestoreMovementDefaults();
// Reset timers
JumpTimer = 0.0f;
} }
void USNGCharacterMovementComponent::TickComponent(float DeltaTime, ELevelTick Tick, void USNGCharacterMovementComponent::TickComponent(float DeltaTime, ELevelTick Tick,

View File

@ -4,7 +4,7 @@
#include "Weapons/SNGInstantRangedWeapon.h" #include "Weapons/SNGInstantRangedWeapon.h"
#include "DrawDebugHelpers.h" #include "DrawDebugHelpers.h"
#include "Characters/SNGCharacterBase.h" #include "Characters/SNGCharacterBase_DEPRECATED.h"
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
#include "Particles/ParticleSystemComponent.h" #include "Particles/ParticleSystemComponent.h"
#include "PhysicalMaterials/PhysicalMaterial.h" #include "PhysicalMaterials/PhysicalMaterial.h"
@ -107,7 +107,7 @@ void ASNGInstantRangedWeapon::DoLineTrace(FRotator SpreadOffset)
if(HitData.HitstopApplicationType == ESNGHitstopApplicationType::Both || if(HitData.HitstopApplicationType == ESNGHitstopApplicationType::Both ||
HitData.HitstopApplicationType == ESNGHitstopApplicationType::CauserOnly) HitData.HitstopApplicationType == ESNGHitstopApplicationType::CauserOnly)
{ {
ASNGCharacterBase* OwnerAsChar = Cast<ASNGCharacterBase>(GetOwner()); ASNGCharacterBase_DEPRECATED* OwnerAsChar = Cast<ASNGCharacterBase_DEPRECATED>(GetOwner());
OwnerAsChar->ApplyHitStop(HitData.StopTime, HitData.SlowTime); OwnerAsChar->ApplyHitStop(HitData.StopTime, HitData.SlowTime);
} }

View File

@ -4,7 +4,7 @@
#include "Weapons/SNGMeleeWeaponBase.h" #include "Weapons/SNGMeleeWeaponBase.h"
#include "Characters/SNGCharacterBase.h" #include "Characters/SNGCharacterBase_DEPRECATED.h"
#include "Kismet/KismetSystemLibrary.h" #include "Kismet/KismetSystemLibrary.h"
#include "SwordNGun/SwordNGun.h" #include "SwordNGun/SwordNGun.h"
@ -61,7 +61,7 @@ void ASNGMeleeWeaponBase::DoSphereCast(FSNGHitData const& HitData, bool Override
if(HitData.HitstopApplicationType == ESNGHitstopApplicationType::Both || if(HitData.HitstopApplicationType == ESNGHitstopApplicationType::Both ||
HitData.HitstopApplicationType == ESNGHitstopApplicationType::CauserOnly) HitData.HitstopApplicationType == ESNGHitstopApplicationType::CauserOnly)
{ {
ASNGCharacterBase* OwnerAsChar = Cast<ASNGCharacterBase>(GetOwner()); ASNGCharacterBase_DEPRECATED* OwnerAsChar = Cast<ASNGCharacterBase_DEPRECATED>(GetOwner());
OwnerAsChar->ApplyHitStop(HitData.StopTime, HitData.SlowTime); OwnerAsChar->ApplyHitStop(HitData.StopTime, HitData.SlowTime);
} }

View File

@ -0,0 +1,174 @@
// Project Sword & Gun Copyright © 2021 Kevin Poretti
#pragma once
#include "CoreMinimal.h"
#include "Components/SNGCharacterMovementComponent.h"
#include "Components/SNGHealthComponent.h"
#include "Components/SNGStateMachineComponent.h"
#include "GameFramework/Character.h"
#include "Interfaces/SNGEventProcessorInterface.h"
#include "Interfaces/SNGWeaponUserInterface.h"
#include "SNGCharacterBase_DEPRECATED.generated.h"
UCLASS()
class SWORDNGUN_API ASNGCharacterBase_DEPRECATED : public ACharacter, public ISNGEventProcessorInterface, public ISNGWeaponUserInterface
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
ASNGCharacterBase_DEPRECATED(const FObjectInitializer& ObjectInitializer);
/*********************************************************************
* Flags
********************************************************************/
UFUNCTION(BlueprintCallable)
void DisableAllActions();
UFUNCTION(BlueprintCallable)
void EnableAllActions();
// NOTE(kevin): should be a blueprint setter but I could not get that working for the life of me
UFUNCTION(BlueprintCallable)
void SetCanMove(bool CanMove);
UFUNCTION(BlueprintGetter)
bool CanMove();
// NOTE(kevin): should be a blueprint setter but I could not get that working for the life of me
// should also probably be a protagonist/player character specific thing
UFUNCTION(BlueprintCallable)
void SetCanCharacterJump(bool CanJump);
UFUNCTION(BlueprintGetter)
bool CanCharacterJump();
// NOTE(kevin): should be a blueprint setter but I could not get that working for the life of me
UFUNCTION(BlueprintCallable)
void SetCanAttack(bool CanAttack);
UFUNCTION(BlueprintGetter)
bool CanAttack();
// NOTE(kevin): should be a blueprint setter but I could not get that working for the life of me
// should also probably be a protagonist/player character specific thing
UFUNCTION(BlueprintCallable)
void SetCanDodge(bool CanDodge);
UFUNCTION(BlueprintGetter)
bool CanDodge();
protected:
UPROPERTY(BlueprintReadOnly)
bool bCanMove;
UPROPERTY(BlueprintReadOnly)
bool bCanJump;
UPROPERTY(BlueprintReadOnly)
bool bCanAttack;
UPROPERTY(BlueprintReadOnly)
bool bCanDodge;
/*********************************************************************
* Movement
********************************************************************/
public:
UFUNCTION(BlueprintCallable, Category="Movement")
void SetIgnoreMovementInput(bool IsIgnored);
UFUNCTION(BlueprintCallable, Category="Movement")
FORCEINLINE class USNGCharacterMovementComponent* GetSNGCharacterMovementComponent() const
{
return SNGCharacterMovementComponent;
}
protected:
USNGCharacterMovementComponent* SNGCharacterMovementComponent;
public:
/*********************************************************************
* Event processing interface
********************************************************************/
// event processing
UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
void PushEvent(FSNGEvent Event);
/**
* The state machine will be handling most if not all of the states
* we simply wrap the state machine's push event implementation since most
* characters that will want to push events to another character will have a reference
* to the character itself rather than the state machine component
*/
virtual void PushEvent_Implementation(FSNGEvent Event);
/*********************************************************************
* Weapons
********************************************************************/
UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
ASNGWeaponBase* GetCurrentWeapon();
virtual ASNGWeaponBase* GetCurrentWeapon_Implementation();
/*********************************************************************
* Damage and hits
********************************************************************/
// damage and related
UFUNCTION(BlueprintCallable)
void ApplyHitStop(float HitStopTime, float HitSlowTime);
virtual void ReceiveHit(FSNGHitData const& HitData, AController* EventInstigator, AActor* DamageCauser);
virtual float TakeDamage(float Damage, struct FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser) override;
protected:
bool bIsInHitStop;
float CurrHitStopTime;
float CurrHitSlowTime;
/*********************************************************************
* Rotate towards target
********************************************************************/
public:
UFUNCTION(BlueprintCallable)
void SetupRotateTowardsTarget(FRotator TargetRotation, float DegreesPerSecond, float MaxRotation);
UFUNCTION(BlueprintCallable)
void RotateTowardsTarget(float DeltaTime);
protected:
FRotator InitialRot;
FRotator TargetRot;
float DegPerSecond;
float MaxRot;
float RotateTime;
float RotateTimeElapsed;
/*********************************************************************
* Components
********************************************************************/
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Components")
USNGStateMachineComponent* StateMachineComponent;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Components")
USNGHealthComponent* HealthComponent;
virtual void Tick(float DeltaSeconds) override;
virtual void PostInitializeComponents() override;
};

View File

@ -3,14 +3,14 @@
#pragma once #pragma once
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "Characters/SNGCharacterBase.h" #include "Characters/SNGCharacterBase_DEPRECATED.h"
#include "SNGEnemyBase.generated.h" #include "SNGEnemyBase.generated.h"
/** /**
* *
*/ */
UCLASS() UCLASS()
class SWORDNGUN_API ASNGEnemyBase : public ASNGCharacterBase class SWORDNGUN_API ASNGEnemyBase : public ASNGCharacterBase_DEPRECATED
{ {
GENERATED_BODY() GENERATED_BODY()

View File

@ -5,7 +5,7 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "Camera/CameraComponent.h" #include "Camera/CameraComponent.h"
#include "Characters/SNGCharacterBase.h" #include "Characters/SNGCharacterBase_DEPRECATED.h"
#include "Components/SNGWeaponInventoryComponent.h" #include "Components/SNGWeaponInventoryComponent.h"
#include "GameFramework/SpringArmComponent.h" #include "GameFramework/SpringArmComponent.h"
@ -27,7 +27,7 @@ struct FMeleeAttackData
* *
*/ */
UCLASS() UCLASS()
class SWORDNGUN_API ASNGProtagonist : public ASNGCharacterBase class SWORDNGUN_API ASNGProtagonist : public ASNGCharacterBase_DEPRECATED
{ {
GENERATED_BODY() GENERATED_BODY()

View File

@ -54,11 +54,7 @@ protected:
/** Force to continuously apply to character when they are holding the jump button */ /** Force to continuously apply to character when they are holding the jump button */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Character Movement: SNG Air Defaults", meta=(ClampMin="0", UIMin="0")) UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Character Movement: SNG Air Defaults", meta=(ClampMin="0", UIMin="0"))
float JumpForce; float DefaultJumpForce;
/** Timer that counts down */
UPROPERTY(BlueprintReadWrite);
float JumpTimer;
/** Minimum height a character must reach before jump force is no longer applied even if the jump input is not being held */ /** Minimum height a character must reach before jump force is no longer applied even if the jump input is not being held */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Character Movement: SNG Air Defaults", meta=(ClampMin="0", UIMin="0")) UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Character Movement: SNG Air Defaults", meta=(ClampMin="0", UIMin="0"))