Initial Commit - Lesson 31 (Commit #1)
This commit is contained in:
149
Source/FPSTemplate/Public/Character/ShooterCharacter.h
Normal file
149
Source/FPSTemplate/Public/Character/ShooterCharacter.h
Normal file
@@ -0,0 +1,149 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/Character.h"
|
||||
#include "GameplayTagContainer.h"
|
||||
#include "Interfaces/PlayerInterface.h"
|
||||
#include "ShooterTypes/ShooterTypes.h"
|
||||
#include "ShooterCharacter.generated.h"
|
||||
|
||||
class UEliminationComponent;
|
||||
class UShooterHealthComponent;
|
||||
class UShooterOverlay;
|
||||
class UShooterHUDComponent;
|
||||
class USpringArmComponent;
|
||||
class UCameraComponent;
|
||||
class UWeaponData;
|
||||
class AWeapon;
|
||||
class UCombatComponent;
|
||||
class UInputAction;
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FWeaponFirstReplicated, AWeapon*, Weapon);
|
||||
|
||||
UCLASS()
|
||||
class FPSTEMPLATE_API AShooterCharacter : public ACharacter, public IPlayerInterface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
AShooterCharacter();
|
||||
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
|
||||
virtual void PossessedBy(AController* NewController) override;
|
||||
virtual void Tick(float DeltaTime) override;
|
||||
virtual void OnRep_PlayerState() override;
|
||||
virtual void BeginDestroy() override;
|
||||
virtual void UnPossessed() override;
|
||||
|
||||
FRotator StartingAimRotation;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
float AO_Yaw;
|
||||
|
||||
float InterpAO_Yaw;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
float MovementOffsetYaw;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
FTransform FABRIK_SocketTransform;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
ETurningInPlace TurningStatus;
|
||||
|
||||
void TurnInPlace(float DeltaTime);
|
||||
|
||||
/** PlayerInterface */
|
||||
virtual FName GetWeaponAttachPoint_Implementation(const FGameplayTag& WeaponType) const override;
|
||||
virtual USkeletalMeshComponent* GetSpecifcPawnMesh_Implementation(bool WantFirstPerson) const override;
|
||||
virtual USkeletalMeshComponent* GetPawnMesh_Implementation() const override;
|
||||
virtual bool IsFirstPerson_Implementation() const override;
|
||||
virtual bool DoDamage_Implementation(float DamageAmount, AActor* DamageInstigator) override;
|
||||
virtual void AddAmmo_Implementation(const FGameplayTag& WeaponType, int32 AmmoAmount) override;
|
||||
virtual AWeapon* GetCurrentWeapon_Implementation() override;
|
||||
virtual int32 GetCarriedAmmo_Implementation() override;
|
||||
virtual void InitializeWidgets_Implementation() override;
|
||||
virtual void Notify_CycleWeapon_Implementation() override;
|
||||
virtual void Notify_ReloadWeapon_Implementation() override;
|
||||
virtual void Initiate_Crouch_Implementation() override;
|
||||
virtual void Initiate_Jump_Implementation() override;
|
||||
virtual bool IsDeadOrDying_Implementation() override;
|
||||
virtual void WeaponReplicated_Implementation() override;
|
||||
/** <end> PlayerInterface */
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
FRotator GetFixedAimRotation() const;
|
||||
|
||||
bool bWeaponFirstReplicated;
|
||||
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FWeaponFirstReplicated OnWeaponFirstReplicated;
|
||||
|
||||
protected:
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Aiming")
|
||||
float DefaultFieldOfView;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Death")
|
||||
TArray<TObjectPtr<UAnimMontage>> DeathMontages;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "HitReact")
|
||||
TArray<TObjectPtr<UAnimMontage>> HitReacts;
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void OnAim(bool bIsAiming);
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void DeathEffects(AActor* DeathInstigator, UAnimMontage* DeathMontage);
|
||||
|
||||
UFUNCTION(NetMulticast, Reliable)
|
||||
void Multicast_HitReact(int32 MontageIndex);
|
||||
|
||||
private:
|
||||
void Input_CycleWeapon();
|
||||
void Input_FireWeapon_Pressed();
|
||||
void Input_FireWeapon_Released();
|
||||
void Input_ReloadWeapon();
|
||||
void Input_Aim_Pressed();
|
||||
void Input_Aim_Released();
|
||||
bool IsLocalFirstPerson() const;
|
||||
|
||||
UFUNCTION()
|
||||
void OnDeathStarted(AActor* DyingActor, AActor* DeathInstigator);
|
||||
|
||||
/** 1st person view */
|
||||
UPROPERTY(VisibleDefaultsOnly, BlueprintReadOnly, Category = Mesh, meta = (AllowPrivateAccess = "true"))
|
||||
TObjectPtr<USkeletalMeshComponent> Mesh1P;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
|
||||
TObjectPtr<UCombatComponent> Combat;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
|
||||
TObjectPtr<UShooterHealthComponent> HealthComponent;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
|
||||
TObjectPtr<UEliminationComponent> EliminationComponent;
|
||||
|
||||
UPROPERTY(VisibleDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
|
||||
TObjectPtr<USpringArmComponent> SpringArm;
|
||||
|
||||
UPROPERTY(VisibleDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
|
||||
TObjectPtr<UCameraComponent> FirstPersonCamera;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category="Input")
|
||||
TObjectPtr<UInputAction> CycleWeaponAction;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category="Input")
|
||||
TObjectPtr<UInputAction> FireWeaponAction;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category="Input")
|
||||
TObjectPtr<UInputAction> ReloadWeaponAction;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category="Input")
|
||||
TObjectPtr<UInputAction> AimAction;
|
||||
|
||||
FTimerHandle InitiializeWidgets_Timer;
|
||||
};
|
||||
|
||||
113
Source/FPSTemplate/Public/Character/ShooterHealthComponent.h
Normal file
113
Source/FPSTemplate/Public/Character/ShooterHealthComponent.h
Normal file
@@ -0,0 +1,113 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "ShooterHealthComponent.generated.h"
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FShooterHealth_DeathEvent, AActor*, OwningActor, AActor*, Instigator);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FourParams(FShooterHealth_AttributeChanged, UShooterHealthComponent*, HealthComponent, float, OldValue, float, NewValue, AActor*, Instigator);
|
||||
|
||||
/**
|
||||
* EDeathState
|
||||
*
|
||||
* Defines current state of death.
|
||||
*/
|
||||
UENUM(BlueprintType)
|
||||
enum class EDeathState : uint8
|
||||
{
|
||||
NotDead = 0,
|
||||
DeathStarted,
|
||||
DeathFinished
|
||||
};
|
||||
|
||||
/**
|
||||
* UShooterHealthComponent
|
||||
*
|
||||
* An actor component used to handle anything related to health.
|
||||
*/
|
||||
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
|
||||
class FPSTEMPLATE_API UShooterHealthComponent : public UActorComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UShooterHealthComponent();
|
||||
|
||||
// Returns the health component if one exists on the specified actor.
|
||||
UFUNCTION(BlueprintPure, Category = "Shooter|Health")
|
||||
static UShooterHealthComponent* FindHealthComponent(const AActor* Actor) { return (Actor ? Actor->FindComponentByClass<UShooterHealthComponent>() : nullptr); }
|
||||
|
||||
// Returns the current health value.
|
||||
UFUNCTION(BlueprintCallable, Category = "Shooter|Health")
|
||||
float GetHealth() const { return Health; };
|
||||
|
||||
// Returns the current maximum health value.
|
||||
UFUNCTION(BlueprintCallable, Category = "Shooter|Health")
|
||||
float GetMaxHealth() const { return MaxHealth; };
|
||||
|
||||
// Returns the current health in the range [0.0, 1.0].
|
||||
UFUNCTION(BlueprintCallable, Category = "Shooter|Health")
|
||||
float GetHealthNormalized() const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Shooter|Health")
|
||||
EDeathState GetDeathState() const { return DeathState; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure = false, Category = "Shooter|Health", Meta = (ExpandBoolAsExecs = "ReturnValue"))
|
||||
bool IsDeadOrDying() const { return (DeathState > EDeathState::NotDead); }
|
||||
|
||||
// Begins the death sequence for the owner.
|
||||
virtual void StartDeath(AActor* Instigator);
|
||||
|
||||
// Ends the death sequence for the owner.
|
||||
virtual void FinishDeath(AActor* Instigator);
|
||||
|
||||
public:
|
||||
|
||||
// Delegate fired when the health value has changed. This is called on the client but the instigator may not be valid
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FShooterHealth_AttributeChanged OnHealthChanged;
|
||||
|
||||
// Delegate fired when the max health value has changed. This is called on the client but the instigator may not be valid
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FShooterHealth_AttributeChanged OnMaxHealthChanged;
|
||||
|
||||
// Delegate fired when the death sequence has started.
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FShooterHealth_DeathEvent OnDeathStarted;
|
||||
|
||||
// Delegate fired when the death sequence has finished.
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FShooterHealth_DeathEvent OnDeathFinished;
|
||||
|
||||
// return true if lethal
|
||||
virtual bool ChangeHealthByAmount(float Amount, AActor* Instigator);
|
||||
virtual void ChangeMaxHealthByAmount(float Amount, AActor* Instigator);
|
||||
|
||||
protected:
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
|
||||
virtual void HandleOutOfHealth();
|
||||
|
||||
UFUNCTION()
|
||||
virtual void OnRep_DeathState(EDeathState OldDeathState);
|
||||
|
||||
// Replicated state used to handle dying.
|
||||
UPROPERTY(ReplicatedUsing = OnRep_DeathState)
|
||||
EDeathState DeathState;
|
||||
|
||||
UPROPERTY(ReplicatedUsing=OnRep_Health)
|
||||
float Health;
|
||||
|
||||
UPROPERTY(ReplicatedUsing=OnRep_MaxHealth)
|
||||
float MaxHealth;
|
||||
|
||||
UFUNCTION()
|
||||
void OnRep_Health(float OldValue);
|
||||
|
||||
UFUNCTION()
|
||||
void OnRep_MaxHealth(float OldValue);
|
||||
|
||||
};
|
||||
155
Source/FPSTemplate/Public/Combat/CombatComponent.h
Normal file
155
Source/FPSTemplate/Public/Combat/CombatComponent.h
Normal file
@@ -0,0 +1,155 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "GameplayTagContainer.h"
|
||||
#include "ShooterTypes/ShooterTypes.h"
|
||||
#include "CombatComponent.generated.h"
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FReticleChangedDelegate, UMaterialInstanceDynamic*, ReticleDynMatInst, const FReticleParams&, ReticleParams, bool, bCurrentlyTargetingPlayer);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FAmmoCounterChangedDelegate, UMaterialInstanceDynamic*, AmmoCounterDynMatInst, int32, RoundsCurrent, int32, RoundsMax);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FTargetingPlayerStatusChangedDelegate, bool, bIsTargetingPlayer);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FRoundFiredDelegate, int32, RoundsCurrent, int32, RoundsMax, int32, RoundsCarried);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FAimingStatusChangedDelegate, bool, bIsAiming);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FCarriedAmmoChangedDelegate, UMaterialInstanceDynamic*, WeaponIconDynMatInst, int32, InCarriedAmmo, int32, RoundsInWeapon);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FiveParams(FRoundReportedDelegate, AActor*, Attacker, AActor*, Victim, bool, bHit, bool, bHeadShot, bool, bLethal);
|
||||
|
||||
class UShooterOverlay;
|
||||
class UWeaponData;
|
||||
|
||||
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
|
||||
class FPSTEMPLATE_API UCombatComponent : public UActorComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UCombatComponent();
|
||||
|
||||
void Initiate_CycleWeapon();
|
||||
void Notify_CycleWeapon();
|
||||
void Notify_ReloadWeapon();
|
||||
void Initiate_FireWeapon_Pressed();
|
||||
void Initiate_FireWeapon_Released();
|
||||
void Initiate_ReloadWeapon();
|
||||
void Initiate_AimPressed();
|
||||
void Initiate_AimReleased();
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void OnAim(bool bIsAiming);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "Shooter|Health")
|
||||
static UCombatComponent* FindCombatComponent(const AActor* Actor) { return (Actor ? Actor->FindComponentByClass<UCombatComponent>() : nullptr); }
|
||||
|
||||
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
|
||||
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
|
||||
void AddAmmo(FGameplayTag WeaponType, int32 AmmoAmount);
|
||||
void InitializeWeaponWidgets() const;
|
||||
void SpawnDefaultInventory();
|
||||
void DestroyInventory();
|
||||
|
||||
UFUNCTION(Reliable, Server)
|
||||
void ServerEquipWeapon(AWeapon* NewWeapon);
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Replicated)
|
||||
bool bAiming;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category=Combat)
|
||||
FReticleChangedDelegate OnReticleChanged;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category=Combat)
|
||||
FAmmoCounterChangedDelegate OnAmmoCounterChanged;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category=Combat)
|
||||
FTargetingPlayerStatusChangedDelegate OnTargetingPlayerStatusChanged;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category=Combat)
|
||||
FRoundFiredDelegate OnRoundFired;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category=Combat)
|
||||
FAimingStatusChangedDelegate OnAimingStatusChanged;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category=Combat)
|
||||
FCarriedAmmoChangedDelegate OnCarriedAmmoChanged;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Weapon")
|
||||
TObjectPtr<UWeaponData> WeaponData;
|
||||
|
||||
UPROPERTY(ReplicatedUsing = OnRep_CarriedAmmo)
|
||||
int32 CarriedAmmo;
|
||||
|
||||
TMap<FGameplayTag, int32> CarriedAmmoMap;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, Category = Inventory)
|
||||
TArray<TSubclassOf<AWeapon>> DefaultInventoryClasses;
|
||||
|
||||
UPROPERTY(Transient, Replicated)
|
||||
TArray<AWeapon*> Inventory;
|
||||
|
||||
UPROPERTY(Transient, ReplicatedUsing = OnRep_CurrentWeapon, BlueprintReadOnly)
|
||||
TObjectPtr<AWeapon> CurrentWeapon;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly)
|
||||
float TraceLength;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
FPlayerHitResult Local_PlayerHitResult;
|
||||
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FRoundReportedDelegate OnRoundReported;
|
||||
|
||||
protected:
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
private:
|
||||
void SetCurrentWeapon(AWeapon* NewWeapon, AWeapon* LastWeapon = nullptr);
|
||||
void AddWeapon(AWeapon* Weapon);
|
||||
void EquipWeapon(AWeapon* Weapon);
|
||||
void Local_CycleWeapon(const int32 WeaponIndex);
|
||||
void FireTimerFinished();
|
||||
int32 AdvanceWeaponIndex();
|
||||
void Local_ReloadWeapon();
|
||||
void Local_Aim(bool bPressed);
|
||||
FVector HitScanTrace(float SweepRadius, FHitResult& OutHit);
|
||||
|
||||
UFUNCTION(Server, Reliable)
|
||||
void Server_CycleWeapon(const int32 WeaponIndex);
|
||||
|
||||
UFUNCTION(NetMulticast, Reliable)
|
||||
void Multicast_CycleWeapon(const int32 WeaponIndex);
|
||||
|
||||
UFUNCTION()
|
||||
void BlendOut_CycleWeapon(UAnimMontage* Montage, bool bInterrupted);
|
||||
|
||||
void Local_FireWeapon();
|
||||
|
||||
UFUNCTION(Server, Reliable)
|
||||
void Server_FireWeapon(const FVector_NetQuantize& TraceStart, const FHitResult& Impact, bool bScoredHit, bool bHeadShot);
|
||||
|
||||
UFUNCTION(NetMulticast, Reliable)
|
||||
void Multicast_FireWeapon(const FHitResult& Impact, int32 AuthAmmo);
|
||||
|
||||
UFUNCTION(Server, Reliable)
|
||||
void Server_ReloadWeapon(bool bLocalOwnerReload = false);
|
||||
|
||||
UFUNCTION(NetMulticast, Reliable)
|
||||
void Multicast_ReloadWeapon(int32 NewWeaponAmmo, int32 NewCarriedAmmo, bool bLocalOwnerReload = false);
|
||||
|
||||
UFUNCTION(Client, Reliable)
|
||||
void Client_ReloadWeapon(int32 NewWeaponAmmo, int32 NewCarriedAmmo);
|
||||
|
||||
UFUNCTION(Server, Reliable)
|
||||
void Server_Aim(bool bPressed);
|
||||
|
||||
UFUNCTION()
|
||||
void OnRep_CurrentWeapon(AWeapon* LastWeapon);
|
||||
|
||||
UFUNCTION()
|
||||
void OnRep_CarriedAmmo();
|
||||
|
||||
int32 Local_WeaponIndex;
|
||||
bool bTriggerPressed;
|
||||
FTimerHandle FireTimer;
|
||||
|
||||
};
|
||||
42
Source/FPSTemplate/Public/Data/SpecialElimData.h
Normal file
42
Source/FPSTemplate/Public/Data/SpecialElimData.h
Normal file
@@ -0,0 +1,42 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/DataAsset.h"
|
||||
#include "ShooterTypes/ShooterTypes.h"
|
||||
#include "SpecialElimData.generated.h"
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FSpecialElimInfo
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
ESpecialElimType ElimType = ESpecialElimType::None;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
FString ElimMessage = FString();
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
TObjectPtr<UTexture2D> ElimIcon = nullptr;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
int32 SequentialElimCount = 0;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
int32 StreakCount = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class FPSTEMPLATE_API USpecialElimData : public UDataAsset
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "SpecialEliminations")
|
||||
TMap<ESpecialElimType, FSpecialElimInfo> SpecialElimInfo;
|
||||
};
|
||||
78
Source/FPSTemplate/Public/Data/WeaponData.h
Normal file
78
Source/FPSTemplate/Public/Data/WeaponData.h
Normal file
@@ -0,0 +1,78 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameplayTagContainer.h"
|
||||
#include "Engine/DataAsset.h"
|
||||
#include "WeaponData.generated.h"
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FPlayerAnims
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
TObjectPtr<UAnimSequence> IdleAnim = nullptr;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
TObjectPtr<UAnimSequence> AimIdleAnim = nullptr;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
TObjectPtr<UAnimSequence> CrouchIdleAnim = nullptr;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
TObjectPtr<UAnimSequence> SprintAnim = nullptr;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
TObjectPtr<UBlendSpace> AimOffset_Hip = nullptr;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
TObjectPtr<UBlendSpace> AimOffset_Aim = nullptr;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
TObjectPtr<UBlendSpace> Strafe_Standing = nullptr;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
TObjectPtr<UBlendSpace> Strafe_Crouching = nullptr;
|
||||
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FMontageData
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
TObjectPtr<UAnimMontage> EquipMontage = nullptr;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
TObjectPtr<UAnimMontage> ReloadMontage = nullptr;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
TObjectPtr<UAnimMontage> FireMontage = nullptr;
|
||||
};
|
||||
|
||||
UCLASS()
|
||||
class FPSTEMPLATE_API UWeaponData : public UDataAsset
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "WeaponData|FirstPerson")
|
||||
TMap<FGameplayTag, FPlayerAnims> FirstPersonAnims;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "WeaponData|ThirdPerson")
|
||||
TMap<FGameplayTag, FPlayerAnims> ThirdPersonAnims;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "WeaponData|Weapons")
|
||||
TMap<FGameplayTag, FMontageData> WeaponMontages;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "WeaponData|Weapons")
|
||||
TMap<FGameplayTag, FName> GripPoints;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "WeaponData|FirstPerson")
|
||||
TMap<FGameplayTag, FMontageData> FirstPersonMontages;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "WeaponData|ThirdPerson")
|
||||
TMap<FGameplayTag, FMontageData> ThirdPersonMontages;
|
||||
};
|
||||
47
Source/FPSTemplate/Public/Elimination/EliminationComponent.h
Normal file
47
Source/FPSTemplate/Public/Elimination/EliminationComponent.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "ShooterTypes/ShooterTypes.h"
|
||||
#include "EliminationComponent.generated.h"
|
||||
|
||||
class AMatchPlayerState;
|
||||
class AMatchGameState;
|
||||
|
||||
UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
|
||||
class FPSTEMPLATE_API UEliminationComponent : public UActorComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UEliminationComponent();
|
||||
|
||||
UFUNCTION()
|
||||
void OnRoundReported(AActor* Attacker, AActor* Victim, bool bHit, bool bHeadShot, bool bLethal);
|
||||
|
||||
protected:
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
private:
|
||||
|
||||
// Time frame to determine sequential elims
|
||||
UPROPERTY(EditDefaultsOnly, Category = Elimination)
|
||||
float SequentialElimInterval;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, Category = Elimination)
|
||||
int32 ElimsNeededForStreak;
|
||||
|
||||
float LastElimTime;
|
||||
int32 SequentialElims;
|
||||
int32 Streak;
|
||||
|
||||
AMatchPlayerState* GetPlayerStateFromActor(AActor* Actor);
|
||||
void ProcessHitOrMiss(bool bHit, AMatchPlayerState* AttackerPS);
|
||||
void ProcessElimination(bool bHeadShot, AMatchPlayerState* AttackerPS, AMatchPlayerState* VictimPS);
|
||||
void ProcessHeadshot(bool bHeadShot, ESpecialElimType& SpecialElimType, AMatchPlayerState* AttackerPS);
|
||||
void ProcessSequentialEliminations(AMatchPlayerState* AttackerPS, ESpecialElimType& SpecialElimType);
|
||||
void ProcessStreaks(AMatchPlayerState* AttackerPS, AMatchPlayerState* VictimPS, ESpecialElimType& SpecialElimType);
|
||||
void HandleFirstBlood(AMatchGameState* GameState, ESpecialElimType& SpecialElimType, AMatchPlayerState* AttackerPS);
|
||||
void UpdateLeaderStatus(AMatchGameState* GameState, ESpecialElimType& SpecialElimType, AMatchPlayerState* AttackerPS, AMatchPlayerState* VictimPS);
|
||||
bool HasSpecialElimTypes(const ESpecialElimType& SpecialElimType);
|
||||
};
|
||||
37
Source/FPSTemplate/Public/Game/MatchGameState.h
Normal file
37
Source/FPSTemplate/Public/Game/MatchGameState.h
Normal file
@@ -0,0 +1,37 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/GameState.h"
|
||||
#include "MatchGameState.generated.h"
|
||||
|
||||
class AMatchPlayerState;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class FPSTEMPLATE_API AMatchGameState : public AGameState
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
AMatchGameState();
|
||||
|
||||
AMatchPlayerState* GetLeader() const;
|
||||
|
||||
void UpdateLeader();
|
||||
bool HasFirstBloodBeenHad() const { return bHasFirstBloodBeenHad; }
|
||||
bool IsTiedForTheLead(AMatchPlayerState* PlayerState);
|
||||
protected:
|
||||
virtual void BeginPlay() override;
|
||||
private:
|
||||
|
||||
UPROPERTY()
|
||||
TArray<TObjectPtr<AMatchPlayerState>> Leaders;
|
||||
|
||||
UPROPERTY()
|
||||
TArray<TObjectPtr<AMatchPlayerState>> SortedPlayerStates;
|
||||
|
||||
bool bHasFirstBloodBeenHad;
|
||||
};
|
||||
44
Source/FPSTemplate/Public/Game/ShooterGameMode.h
Normal file
44
Source/FPSTemplate/Public/Game/ShooterGameMode.h
Normal file
@@ -0,0 +1,44 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "ShooterGameModeBase.h"
|
||||
|
||||
#if WITH_GAMELIFT
|
||||
#include "GameLiftServerSDK.h"
|
||||
#endif
|
||||
|
||||
#include "ShooterGameMode.generated.h"
|
||||
|
||||
|
||||
|
||||
struct FProcessParameters;
|
||||
|
||||
DECLARE_LOG_CATEGORY_EXTERN(LogShooterGameMode, Log, All);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class FPSTEMPLATE_API AShooterGameMode : public AShooterGameModeBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
AShooterGameMode();
|
||||
|
||||
protected:
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
private:
|
||||
|
||||
void InitGameLift();
|
||||
#if WITH_GAMELIFT
|
||||
void SetServerParameters(TSharedPtr<FServerParameters> OutServerParameters);
|
||||
void LogServerParameters(TSharedPtr<FServerParameters> ServerParameters);
|
||||
#endif
|
||||
void ParseCommandLinePort(int32& OutPort);
|
||||
|
||||
TSharedPtr<FProcessParameters> ProcessParameters;
|
||||
};
|
||||
30
Source/FPSTemplate/Public/Game/ShooterGameModeBase.h
Normal file
30
Source/FPSTemplate/Public/Game/ShooterGameModeBase.h
Normal file
@@ -0,0 +1,30 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/GameMode.h"
|
||||
#include "ShooterGameModeBase.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class FPSTEMPLATE_API AShooterGameModeBase : public AGameMode
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
AShooterGameModeBase();
|
||||
virtual void Tick(float DeltaTime) override;
|
||||
virtual void StartPlayerElimination(float ElimTime, ACharacter* ElimmedCharacter, class APlayerController* VictimController, APlayerController* AttackerController);
|
||||
|
||||
UPROPERTY()
|
||||
TMap<APlayerController*, FTimerHandle> Timers;
|
||||
|
||||
virtual void PlayerEliminated(ACharacter* ElimmedCharacter, class APlayerController* VictimController, APlayerController* AttackerController);
|
||||
virtual void RequestRespawn(ACharacter* ElimmedCharacter, AController* ElimmedController);
|
||||
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, Category="Respawning")
|
||||
float RespawnTime;
|
||||
};
|
||||
90
Source/FPSTemplate/Public/Interfaces/PlayerInterface.h
Normal file
90
Source/FPSTemplate/Public/Interfaces/PlayerInterface.h
Normal file
@@ -0,0 +1,90 @@
|
||||
#pragma once
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/Interface.h"
|
||||
#include "PlayerInterface.generated.h"
|
||||
|
||||
class UShooterOverlay;
|
||||
struct FGameplayTag;
|
||||
class AWeapon;
|
||||
|
||||
// This class does not need to be modified.
|
||||
UINTERFACE(MinimalAPI)
|
||||
class UPlayerInterface : public UInterface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
};
|
||||
|
||||
class FPSTEMPLATE_API IPlayerInterface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
// Add interface functions to this class. This is the class that will be inherited to implement this interface.
|
||||
|
||||
public:
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
|
||||
FName GetWeaponAttachPoint(const FGameplayTag& WeaponType) const;
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
|
||||
USkeletalMeshComponent* GetSpecifcPawnMesh(bool WantFirstPerson) const;
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
|
||||
USkeletalMeshComponent* GetPawnMesh() const;
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
|
||||
bool IsFirstPerson() const;
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
|
||||
void Initiate_CycleWeapon();
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
|
||||
void Notify_CycleWeapon();
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
|
||||
void Notify_ReloadWeapon();
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent)
|
||||
void Initiate_FireWeapon_Pressed();
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent)
|
||||
void Initiate_FireWeapon_Released();
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent)
|
||||
void Initiate_ReloadWeapon();
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent)
|
||||
void Initiate_Aim_Pressed();
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent)
|
||||
void Initiate_Aim_Released();
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent)
|
||||
void Initiate_Crouch();
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent)
|
||||
void Initiate_Jump();
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
|
||||
bool DoDamage(float DamageAmount, AActor* DamageInstigator);
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
|
||||
void AddAmmo(const FGameplayTag& WeaponType, int32 AmmoAmount);
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
|
||||
AWeapon* GetCurrentWeapon();
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
|
||||
int32 GetCarriedAmmo();
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
|
||||
void InitializeWidgets();
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
|
||||
bool IsDeadOrDying();
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
|
||||
void WeaponReplicated();
|
||||
};
|
||||
92
Source/FPSTemplate/Public/Player/MatchPlayerState.h
Normal file
92
Source/FPSTemplate/Public/Player/MatchPlayerState.h
Normal file
@@ -0,0 +1,92 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/PlayerState.h"
|
||||
#include "Data/SpecialElimData.h"
|
||||
|
||||
#include "MatchPlayerState.generated.h"
|
||||
|
||||
enum class ESpecialElimType : uint16;
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnScoreChanged, int32, NewScore);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class FPSTEMPLATE_API AMatchPlayerState : public APlayerState
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
AMatchPlayerState();
|
||||
|
||||
void AddScoredElim();
|
||||
void AddDefeat();
|
||||
void AddHit();
|
||||
void AddMiss();
|
||||
APlayerState* GetLastAttacker() const { return LastAttacker; }
|
||||
void SetLastAttacker(APlayerState* Attacker) { LastAttacker = Attacker; }
|
||||
bool IsOnStreak() const { return bOnStreak; }
|
||||
void SetOnStreak(bool bIsOnStreak) { bOnStreak = bIsOnStreak; }
|
||||
int32 GetScoredElims() const { return ScoredElims; }
|
||||
|
||||
void AddHeadShotElim();
|
||||
void AddSequentialElim(int32 SequenceCount);
|
||||
void UpdateHighestStreak(int32 StreakCount);
|
||||
void AddRevengeElim();
|
||||
void AddDethroneElim();
|
||||
void AddShowStopperElim();
|
||||
void GotFirstBlood();
|
||||
void IsTheWinner();
|
||||
|
||||
UFUNCTION(Client, Reliable)
|
||||
void Client_SpecialElim(const ESpecialElimType& SpecialElim, int32 SequentialElimCount, int32 StreakCount, int32 ElimScore);
|
||||
|
||||
UFUNCTION(Client, Reliable)
|
||||
void Client_ScoredElim(int32 ElimScore);
|
||||
|
||||
UFUNCTION(Client, Reliable)
|
||||
void Client_LostTheLead();
|
||||
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FOnScoreChanged OnScoreChanged;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
TObjectPtr<USpecialElimData> SpecialElimData;
|
||||
|
||||
TArray<ESpecialElimType> DecodeElimBitmask(ESpecialElimType ElimTypeBitmask);
|
||||
|
||||
protected:
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, Category = "UI")
|
||||
TSubclassOf<UUserWidget> SpecialElimWidgetClass;
|
||||
|
||||
private:
|
||||
int32 ScoredElims;
|
||||
int32 Defeats;
|
||||
int32 Hits;
|
||||
int32 Misses;
|
||||
bool bOnStreak;
|
||||
|
||||
int32 HeadShotElims;
|
||||
TMap<int32, int32> SequentialElims;
|
||||
int32 HighestStreak;
|
||||
int32 RevengeElims;
|
||||
int32 DethroneElims;
|
||||
int32 ShowStopperElims;
|
||||
bool bFirstBlood;
|
||||
bool bWinner;
|
||||
|
||||
UPROPERTY()
|
||||
TObjectPtr<APlayerState> LastAttacker;
|
||||
|
||||
TQueue<FSpecialElimInfo> SpecialElimQueue;
|
||||
bool bIsProcessingQueue;
|
||||
|
||||
void ProcessNextSpecialElim();
|
||||
void ShowSpecialElim(const FSpecialElimInfo& ElimMessageInfo);
|
||||
};
|
||||
|
||||
|
||||
58
Source/FPSTemplate/Public/Player/ShooterPlayerController.h
Normal file
58
Source/FPSTemplate/Public/Player/ShooterPlayerController.h
Normal file
@@ -0,0 +1,58 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/PlayerController.h"
|
||||
#include "ShooterPlayerController.generated.h"
|
||||
|
||||
struct FInputActionValue;
|
||||
class UInputMappingContext;
|
||||
class UInputAction;
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnPlayerStateReplicated);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class FPSTEMPLATE_API AShooterPlayerController : public APlayerController
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
AShooterPlayerController();
|
||||
bool bPawnAlive;
|
||||
virtual void OnPossess(APawn* InPawn) override;
|
||||
virtual void OnRep_PlayerState() override;
|
||||
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FOnPlayerStateReplicated OnPlayerStateReplicated;
|
||||
protected:
|
||||
virtual void BeginPlay() override;
|
||||
virtual void SetupInputComponent() override;
|
||||
private:
|
||||
UPROPERTY(EditAnywhere, Category="Input")
|
||||
TObjectPtr<UInputMappingContext> ShooterIMC;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category="Input")
|
||||
TObjectPtr<UInputAction> MoveAction;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category="Input")
|
||||
TObjectPtr<UInputAction> LookAction;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category="Input")
|
||||
TObjectPtr<UInputAction> CrouchAction;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category="Input")
|
||||
TObjectPtr<UInputAction> JumpAction;
|
||||
|
||||
|
||||
void Input_Move(const FInputActionValue& InputActionValue);
|
||||
void Input_Look(const FInputActionValue& InputActionValue);
|
||||
void Input_Crouch();
|
||||
void Input_Jump();
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
89
Source/FPSTemplate/Public/ShooterTypes/ShooterTypes.h
Normal file
89
Source/FPSTemplate/Public/ShooterTypes/ShooterTypes.h
Normal file
@@ -0,0 +1,89 @@
|
||||
#pragma once
|
||||
|
||||
#include "ShooterTypes.generated.h"
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FPlayerHitResult
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
FVector_NetQuantize Start = FVector_NetQuantize::ZeroVector;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
FVector_NetQuantize End = FVector_NetQuantize::ZeroVector;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
bool bHitPlayer = false;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
bool bHitPlayerLastFrame = false;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
bool bHeadShot = false;
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FReticleParams
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere)
|
||||
float ScaleFactor_Targeting = 0.f;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere)
|
||||
float ScaleFactor_NotTargeting = 0.f;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere)
|
||||
float ScaleFactor_Aiming = 0.f;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere)
|
||||
float ScaleFactor_NotAiming = 0.f;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere)
|
||||
float ShapeCutFactor_Aiming = 0.f;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere)
|
||||
float ShapeCutFactor_NotAiming = 0.f;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere)
|
||||
float ShapeCutFactor_RoundFired = 0.f;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere)
|
||||
float ScaleFactor_RoundFired = 0.f;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere)
|
||||
float AimingInterpSpeed = 15.f;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere)
|
||||
float TargetingPlayerInterpSpeed = 10.f;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere)
|
||||
float RoundFiredInterpSpeed = 20.f;
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class ETurningInPlace : uint8
|
||||
{
|
||||
Left UMETA(DisplayName = "TurningLeft"),
|
||||
Right UMETA(DisplayName = "TurningRight"),
|
||||
NotTurning UMETA(DisplayName = "NotTurning")
|
||||
};
|
||||
|
||||
UENUM(meta = (Bitflags))
|
||||
enum class ESpecialElimType : uint16
|
||||
{
|
||||
None = 0,
|
||||
Headshot = 1 << 0, // 00000000 00000001
|
||||
Sequential = 1 << 1, // 00000000 00000010
|
||||
Streak = 1 << 2, // 00000000 00000100
|
||||
Revenge = 1 << 3, // 00000000 00001000
|
||||
Dethrone = 1 << 4, // 00000000 00010000
|
||||
Showstopper = 1 << 5, // 00000000 00100000
|
||||
FirstBlood = 1 << 6, // 00000000 01000000
|
||||
GainedTheLead = 1 << 7, // 00000000 10000000
|
||||
TiedTheLeader = 1 << 8, // 00000001 00000000
|
||||
LostTheLead = 1 << 9 // 00000010 00000000
|
||||
};
|
||||
|
||||
ENUM_CLASS_FLAGS(ESpecialElimType)
|
||||
11
Source/FPSTemplate/Public/Tags/ShooterGameplayTags.h
Normal file
11
Source/FPSTemplate/Public/Tags/ShooterGameplayTags.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "NativeGameplayTags.h"
|
||||
|
||||
namespace ShooterTags
|
||||
{
|
||||
UE_DECLARE_GAMEPLAY_TAG_EXTERN(TAG_WeaponType_None);
|
||||
UE_DECLARE_GAMEPLAY_TAG_EXTERN(TAG_WeaponType_Pistol);
|
||||
UE_DECLARE_GAMEPLAY_TAG_EXTERN(TAG_WeaponType_Rifle);
|
||||
}
|
||||
33
Source/FPSTemplate/Public/UI/Elims/ScoreWidget.h
Normal file
33
Source/FPSTemplate/Public/UI/Elims/ScoreWidget.h
Normal file
@@ -0,0 +1,33 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Blueprint/UserWidget.h"
|
||||
#include "ScoreWidget.generated.h"
|
||||
|
||||
class UTextBlock;
|
||||
class AMatchPlayerState;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class FPSTEMPLATE_API UScoreWidget : public UUserWidget
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
virtual void NativeConstruct() override;
|
||||
|
||||
UPROPERTY(meta = (BindWidget))
|
||||
UTextBlock* ScoreText;
|
||||
|
||||
protected:
|
||||
UFUNCTION()
|
||||
void OnScoreChanged(int32 NewScore);
|
||||
|
||||
UFUNCTION()
|
||||
void OnPlayerStateInitialized();
|
||||
|
||||
AMatchPlayerState* GetPlayerState() const;
|
||||
};
|
||||
29
Source/FPSTemplate/Public/UI/Elims/SpecialElimWidget.h
Normal file
29
Source/FPSTemplate/Public/UI/Elims/SpecialElimWidget.h
Normal file
@@ -0,0 +1,29 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Blueprint/UserWidget.h"
|
||||
#include "SpecialElimWidget.generated.h"
|
||||
|
||||
class UTextBlock;
|
||||
class UImage;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class FPSTEMPLATE_API USpecialElimWidget : public UUserWidget
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UPROPERTY(meta = (BindWidget))
|
||||
TObjectPtr<UTextBlock> ElimText;
|
||||
|
||||
UPROPERTY(meta = (BindWidget), BlueprintReadOnly, EditDefaultsOnly)
|
||||
TObjectPtr<UImage> ElimImage;
|
||||
|
||||
void InitializeWidget(const FString& InElimMessage, UTexture2D* InElimTexture);
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
static void CenterWidget(UUserWidget* Widget, float VerticalRatio = 0.f);
|
||||
};
|
||||
49
Source/FPSTemplate/Public/UI/ShooterAmmoCounter.h
Normal file
49
Source/FPSTemplate/Public/UI/ShooterAmmoCounter.h
Normal file
@@ -0,0 +1,49 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Blueprint/UserWidget.h"
|
||||
#include "ShooterAmmoCounter.generated.h"
|
||||
|
||||
class UImage;
|
||||
class UTextBlock;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class FPSTEMPLATE_API UShooterAmmoCounter : public UUserWidget
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
|
||||
virtual void NativeConstruct() override;
|
||||
|
||||
UPROPERTY(meta = (BindWidget))
|
||||
TObjectPtr<UImage> Image_WeaponIcon;
|
||||
|
||||
UPROPERTY(meta = (BindWidget))
|
||||
TObjectPtr<UTextBlock> Text_Ammo;
|
||||
|
||||
|
||||
|
||||
UPROPERTY()
|
||||
TObjectPtr<UMaterialInstanceDynamic> CurrentWeaponIcon_DynMatInst;
|
||||
|
||||
private:
|
||||
|
||||
int32 TotalAmmo;
|
||||
|
||||
UFUNCTION()
|
||||
void OnPossessedPawnChanged(APawn* OldPawn, APawn* NewPawn);
|
||||
|
||||
UFUNCTION()
|
||||
void OnCarriedAmmoChanged(UMaterialInstanceDynamic* WeaponIconDynMatInst, int32 InCarriedAmmo, int32 RoundsInWeapon);
|
||||
|
||||
UFUNCTION()
|
||||
void OnRoundFired(int32 RoundsCurrent, int32 RoundsMax, int32 RoundsCarried);
|
||||
|
||||
UFUNCTION()
|
||||
void OnWeaponFirstReplicated(AWeapon* Weapon);
|
||||
};
|
||||
31
Source/FPSTemplate/Public/UI/ShooterHUD.h
Normal file
31
Source/FPSTemplate/Public/UI/ShooterHUD.h
Normal file
@@ -0,0 +1,31 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/HUD.h"
|
||||
#include "ShooterHUD.generated.h"
|
||||
|
||||
class UUserWidget;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class FPSTEMPLATE_API AShooterHUD : public AHUD
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UUserWidget* GetShooterOverlay() {return Overlay;}
|
||||
|
||||
protected:
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
private:
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, Category = "Overlay")
|
||||
TSubclassOf<UUserWidget> ShooterOverlayClass;
|
||||
|
||||
UPROPERTY()
|
||||
TObjectPtr<UUserWidget> Overlay;
|
||||
};
|
||||
86
Source/FPSTemplate/Public/UI/ShooterReticle.h
Normal file
86
Source/FPSTemplate/Public/UI/ShooterReticle.h
Normal file
@@ -0,0 +1,86 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Blueprint/UserWidget.h"
|
||||
#include "ShooterTypes/ShooterTypes.h"
|
||||
#include "ShooterReticle.generated.h"
|
||||
|
||||
namespace Reticle
|
||||
{
|
||||
extern FPSTEMPLATE_API const FName Inner_RGBA;
|
||||
extern FPSTEMPLATE_API const FName RoundedCornerScale;
|
||||
extern FPSTEMPLATE_API const FName ShapeCutThickness;
|
||||
}
|
||||
|
||||
namespace Ammo
|
||||
{
|
||||
extern FPSTEMPLATE_API const FName Rounds_Current;
|
||||
extern FPSTEMPLATE_API const FName Rounds_Max;
|
||||
}
|
||||
|
||||
class UImage;
|
||||
class AWeapon;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class FPSTEMPLATE_API UShooterReticle : public UUserWidget
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
|
||||
virtual void NativeConstruct() override;
|
||||
virtual void NativeTick(const FGeometry& MyGeometry, float InDeltaTime) override;
|
||||
|
||||
UPROPERTY(meta = (BindWidget))
|
||||
TObjectPtr<UImage> Image_Reticle;
|
||||
|
||||
UPROPERTY(meta = (BindWidget))
|
||||
TObjectPtr<UImage> Image_AmmoCounter;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
UPROPERTY()
|
||||
TObjectPtr<UMaterialInstanceDynamic> CurrentReticle_DynMatInst;
|
||||
|
||||
UPROPERTY()
|
||||
TObjectPtr<UMaterialInstanceDynamic> CurrentAmmoCounter_DynMatInst;
|
||||
|
||||
FReticleParams CurrentReticleParams;
|
||||
float BaseCornerScaleFactor;
|
||||
float _BaseCornerScaleFactor_TargetingPlayer;
|
||||
float _BaseCornerScaleFactor_Aiming;
|
||||
float _BaseCornerScaleFactor_RoundFired;
|
||||
float BaseShapeCutFactor;
|
||||
float _BaseShapeCutFactor_Aiming;
|
||||
float _BaseShapeCutFactor_RoundFired;
|
||||
bool bTargetingPlayer;
|
||||
bool bAiming;
|
||||
|
||||
UFUNCTION()
|
||||
void OnPossessedPawnChanged(APawn* OldPawn, APawn* NewPawn);
|
||||
|
||||
UFUNCTION()
|
||||
void OnReticleChange(UMaterialInstanceDynamic* ReticleDynMatInst, const FReticleParams& ReticleParams, bool bCurrentlyTargetingPlayer = false);
|
||||
|
||||
UFUNCTION()
|
||||
void OnAmmoCounterChange(UMaterialInstanceDynamic* AmmoCounterDynMatInst, int32 RoundsCurrent, int32 RoundsMax);
|
||||
|
||||
UFUNCTION()
|
||||
void OnTargetingPlayerStatusChanged(bool bIsTargetingPlayer);
|
||||
|
||||
UFUNCTION()
|
||||
void OnRoundFired(int32 RoundsCurrent, int32 RoundsMax, int32 RoundsCarried);
|
||||
|
||||
UFUNCTION()
|
||||
void OnAimingStatusChanged(bool bIsAiming);
|
||||
|
||||
UFUNCTION()
|
||||
void OnWeaponFirstReplicated(AWeapon* Weapon);
|
||||
};
|
||||
|
||||
|
||||
164
Source/FPSTemplate/Public/Weapon/Weapon.h
Normal file
164
Source/FPSTemplate/Public/Weapon/Weapon.h
Normal file
@@ -0,0 +1,164 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "GameplayTagContainer.h"
|
||||
#include "ShooterTypes/ShooterTypes.h"
|
||||
#include "Weapon.generated.h"
|
||||
|
||||
struct FPlayerHitResult;
|
||||
|
||||
/** Enum used to describe what state the weapon is currently in. */
|
||||
UENUM(BlueprintType)
|
||||
namespace EWeaponState
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Idle,
|
||||
Firing,
|
||||
Reloading,
|
||||
Equipping,
|
||||
};
|
||||
}
|
||||
|
||||
UENUM(BlueprintType)
|
||||
namespace EFireType
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Auto,
|
||||
SemiAuto
|
||||
};
|
||||
}
|
||||
|
||||
UCLASS()
|
||||
class FPSTEMPLATE_API AWeapon : public AActor
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
AWeapon();
|
||||
virtual void Tick(float DeltaTime) override;
|
||||
virtual void OnRep_Instigator() override;
|
||||
|
||||
/** perform initial setup */
|
||||
virtual void PostInitializeComponents() override;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, EditAnywhere)
|
||||
FGameplayTag WeaponType;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Firing the Weapon
|
||||
|
||||
void Local_Fire(const FVector& ImpactPoint, const FVector& ImpactNormal, TEnumAsByte<EPhysicalSurface> SurfaceType, bool bIsFirstPerson);
|
||||
int32 Auth_Fire();
|
||||
void Rep_Fire(int32 AuthAmmo);
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void FireEffects(const FVector& ImpactPoint, const FVector& ImpactNormal, EPhysicalSurface SurfaceType, bool bIsFirstPerson);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Inventory
|
||||
|
||||
/** [server] weapon was added to pawn's inventory */
|
||||
virtual void OnEnterInventory(APawn* NewOwner);
|
||||
|
||||
/** weapon is holstered by owner pawn */
|
||||
virtual void OnUnEquip();
|
||||
|
||||
/** weapon is being equipped by owner pawn */
|
||||
virtual void OnEquip(const AWeapon* LastWeapon);
|
||||
|
||||
/** set the weapon's owning pawn */
|
||||
void SetOwningPawn(APawn* NewOwningPawn);
|
||||
|
||||
/** get weapon mesh (needs pawn owner to determine variant) */
|
||||
USkeletalMeshComponent* GetWeaponMesh() const;
|
||||
|
||||
/** update weapon state */
|
||||
void SetWeaponState(EWeaponState::Type NewState);
|
||||
|
||||
EWeaponState::Type GetWeaponState() const;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
int32 MagCapacity;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
int32 Ammo;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
int32 Sequence;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
int32 StartingCarriedAmmo;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
float Damage;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
float AimFieldOfView;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
float HeadShotDamage;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
float FireTime;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
TEnumAsByte<EFireType::Type> FireType;
|
||||
|
||||
USkeletalMeshComponent* GetMesh1P() const;
|
||||
USkeletalMeshComponent* GetMesh3P() const;
|
||||
|
||||
UMaterialInstanceDynamic* GetReticleDynamicMaterialInstance();
|
||||
UMaterialInstanceDynamic* GetAmmoCounterDynamicMaterialInstance();
|
||||
UMaterialInstanceDynamic* GetWeaponIconDynamicMaterialInstance();
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, Category=Reticle)
|
||||
FReticleParams ReticleParams;
|
||||
|
||||
protected:
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Inventory
|
||||
|
||||
/** attaches weapon mesh to pawn's mesh */
|
||||
void AttachMeshToPawn();
|
||||
|
||||
/** detaches weapon mesh from pawn */
|
||||
void DetachMeshFromPawn();
|
||||
|
||||
private:
|
||||
/** weapon mesh: 1st person view */
|
||||
UPROPERTY(VisibleDefaultsOnly, BlueprintReadOnly, Category=Mesh, meta = (AllowPrivateAccess = "true"))
|
||||
TObjectPtr<USkeletalMeshComponent> Mesh1P;
|
||||
|
||||
/** weapon mesh: 3rd person view */
|
||||
UPROPERTY(VisibleDefaultsOnly, BlueprintReadOnly, Category=Mesh, meta = (AllowPrivateAccess = "true"))
|
||||
TObjectPtr<USkeletalMeshComponent> Mesh3P;
|
||||
|
||||
/** current weapon state */
|
||||
EWeaponState::Type CurrentState;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, Category=Weapon)
|
||||
TObjectPtr<UMaterialInterface> ReticleMaterial;
|
||||
|
||||
UPROPERTY()
|
||||
TObjectPtr<UMaterialInstanceDynamic> DynMatInst_Reticle;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, Category=Weapon)
|
||||
TObjectPtr<UMaterialInterface> AmmoCounterMaterial;
|
||||
|
||||
UPROPERTY()
|
||||
TObjectPtr<UMaterialInstanceDynamic> DynMatInst_AmmoCounter;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, Category=Weapon)
|
||||
TObjectPtr<UMaterialInterface> WeaponIconMaterial;
|
||||
|
||||
UPROPERTY()
|
||||
TObjectPtr<UMaterialInstanceDynamic> DynMatInst_WeaponIcon;
|
||||
|
||||
};
|
||||
Reference in New Issue
Block a user