Skip to content

Commit

Permalink
Use custom classes via config, moved pawndata from PlayerState to ECR…
Browse files Browse the repository at this point in the history
…Character
  • Loading branch information
JediKnightChan committed Dec 28, 2022
1 parent 443c642 commit d3c74be
Show file tree
Hide file tree
Showing 11 changed files with 109 additions and 80 deletions.
12 changes: 12 additions & 0 deletions Config/DefaultGame.ini
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,15 @@ CopyrightNotice=Copyleft: All rights reversed

[/Script/GameplayAbilities.AbilitySystemGlobals]
AbilitySystemGlobalsClassName=/Script/ECR.ECRAbilitySystemGlobals
GlobalGameplayCueManagerClass=/Script/ECR.ECRGameplayCueManager
PredictTargetGameplayEffects=false
bUseDebugTargetFromHud=true
ActivateFailIsDeadName=Ability.ActivateFail.IsDead
ActivateFailCooldownName=Ability.ActivateFail.Cooldown
ActivateFailCostName=Ability.ActivateFail.Cost
ActivateFailTagsBlockedName=Ability.ActivateFail.TagsBlocked
ActivateFailTagsMissingName=Ability.ActivateFail.TagsMissing
ActivateFailNetworkingName=Ability.ActivateFail.Networking

[/Script/ECR.ECRAssetManager]
ECRGameDataPath=/Game/DefaultGameData.DefaultGameData
5 changes: 5 additions & 0 deletions Config/DefaultGameplayTags.ini
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ InvalidTagCharacters="\"\',"
+GameplayTagTableList=/Game/Blueprints/ECR/Data/Tags/CommonGameplayTags.CommonGameplayTags
NumBitsForContainerSize=6
NetIndexFirstBitSegment=16
+GameplayTagList=(Tag="Ability.Type.Action",DevComment="")
+GameplayTagList=(Tag="GameplayCue.Character.DamageTaken",DevComment="")
+GameplayTagList=(Tag="GameplayEffect.DamageType.Basic",DevComment="")
+GameplayTagList=(Tag="InputTag.Look.Mouse",DevComment="")
+GameplayTagList=(Tag="InputTag.Move",DevComment="")
+GameplayTagList=(Tag="Status.Death.Dead",DevComment="")
+GameplayTagList=(Tag="Status.Death.Dying",DevComment="")
4 changes: 2 additions & 2 deletions Config/DefaultInput.ini
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ DoubleClickTime=0.200000
+AxisMappings=(AxisName="Turn Right / Left Mouse",Scale=1.000000,Key=MouseX)
+AxisMappings=(AxisName="Look Up / Down Gamepad",Scale=1.000000,Key=Gamepad_RightY)
+AxisMappings=(AxisName="Look Up / Down Mouse",Scale=-1.000000,Key=MouseY)
DefaultPlayerInputClass=/Script/Engine.PlayerInput
DefaultInputComponentClass=/Script/Engine.InputComponent
DefaultPlayerInputClass=/Script/EnhancedInput.EnhancedPlayerInput
DefaultInputComponentClass=/Script/ECR.ECRInputComponent
DefaultTouchInterface=/Engine/MobileResources/HUD/DefaultVirtualJoysticks.DefaultVirtualJoysticks
-ConsoleKeys=Tilde
+ConsoleKeys=Tilde
Expand Down
52 changes: 51 additions & 1 deletion Source/ECR/Private/Gameplay/Character/ECRCharacter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,16 @@
#include "Gameplay/Player/ECRPlayerState.h"
#include "Net/UnrealNetwork.h"
#include "TimerManager.h"
#include "Components/GameFrameworkComponentManager.h"
#include "Gameplay/Character/ECRPawnData.h"
#include "Gameplay/GAS/ECRAbilitySet.h"

static FName NAME_ECRCharacterCollisionProfile_Capsule(TEXT("ECRPawnCapsule"));
static FName NAME_ECRCharacterCollisionProfile_Mesh(TEXT("ECRPawnMesh"));

const FName AECRCharacter::NAME_ECRAbilityReady("ECRAbilitiesReady");


AECRCharacter::AECRCharacter(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer.SetDefaultSubobjectClass<UECRCharacterMovementComponent>(
ACharacter::CharacterMovementComponentName))
Expand Down Expand Up @@ -128,6 +134,10 @@ void AECRCharacter::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLif
Super::GetLifetimeReplicatedProps(OutLifetimeProps);

DOREPLIFETIME_CONDITION(ThisClass, ReplicatedAcceleration, COND_SimulatedOnly);

FDoRepLifetimeParams SharedParams;
SharedParams.bIsPushBased = true;
DOREPLIFETIME_WITH_PARAMS_FAST(ThisClass, PawnData, SharedParams);
}

void AECRCharacter::PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker)
Expand Down Expand Up @@ -191,12 +201,21 @@ void AECRCharacter::PossessedBy(AController* NewController)
Super::PossessedBy(NewController);

PawnExtComponent->HandleControllerChanged();

UE_LOG(LogTemp, Warning, TEXT("Pawn data is %s"), *(GetNameSafe(PawnData)));

if (GetWorld()->GetNetMode() < NM_Client)
{
UE_LOG(LogTemp, Warning, TEXT("Initting pawn data as server"));
PawnExtComponent->SetPawnData(PawnData);
InitPawnData();
}
}

void AECRCharacter::UnPossessed()
{
AController* const OldController = Controller;

Super::UnPossessed();

PawnExtComponent->HandleControllerChanged();
Expand Down Expand Up @@ -426,6 +445,37 @@ bool AECRCharacter::CanJumpInternal_Implementation() const
return JumpIsAllowedInternal();
}


void AECRCharacter::InitPawnData()
{
ensureMsgf(PawnData, TEXT("ECRCharacter [%s] pawn data is empty"), *(GetNameSafe(this)));

UE_LOG(LogTemp, Warning, TEXT("InitPawnData called"))
if (GetLocalRole() != ROLE_Authority)
{
return;
}

MARK_PROPERTY_DIRTY_FROM_NAME(ThisClass, PawnData, this);

for (const UECRAbilitySet* AbilitySet : PawnData->AbilitySets)
{
if (AbilitySet)
{
UECRAbilitySystemComponent* ECRAbilitySystemComponent = GetECRAbilitySystemComponent();
AbilitySet->GiveToAbilitySystem(ECRAbilitySystemComponent, nullptr);
}
}

UGameFrameworkComponentManager::SendGameFrameworkComponentExtensionEvent(this, NAME_ECRAbilityReady);

ForceNetUpdate();
}

void AECRCharacter::OnRep_PawnData()
{
}

void AECRCharacter::OnRep_ReplicatedAcceleration()
{
if (UECRCharacterMovementComponent* ECRMovementComponent = Cast<UECRCharacterMovementComponent>(
Expand Down
8 changes: 7 additions & 1 deletion Source/ECR/Private/Gameplay/Character/ECRHeroComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,13 @@ void UECRHeroComponent::OnRegister()
{
Super::OnRegister();

UE_LOG(LogTemp, Warning, TEXT("Hero registering"))

if (const APawn* Pawn = GetPawn<APawn>())
{
if (UECRPawnExtensionComponent* PawnExtComp = UECRPawnExtensionComponent::FindPawnExtensionComponent(Pawn))
{
UE_LOG(LogTemp, Warning, TEXT("Hero ready to get in"))
PawnExtComp->OnPawnReadyToInitialize_RegisterAndCall(FSimpleMulticastDelegate::FDelegate::CreateUObject(this, &ThisClass::OnPawnReadyToInitialize));
}
}
Expand Down Expand Up @@ -125,7 +128,7 @@ void UECRHeroComponent::OnPawnReadyToInitialize()
// Don't initialize twice
return;
}

UE_LOG(LogTemp, Warning, TEXT("Hero initing"));
APawn* Pawn = GetPawn<APawn>();
if (!Pawn)
{
Expand All @@ -140,6 +143,7 @@ void UECRHeroComponent::OnPawnReadyToInitialize()

if (UECRPawnExtensionComponent* PawnExtComp = UECRPawnExtensionComponent::FindPawnExtensionComponent(Pawn))
{
UE_LOG(LogTemp, Warning, TEXT("Hero initing as"));
PawnData = PawnExtComp->GetPawnData<UECRPawnData>();

// The player state holds the persistent data for this player (state that persists across deaths and multiple pawns).
Expand All @@ -151,6 +155,7 @@ void UECRHeroComponent::OnPawnReadyToInitialize()
{
if (Pawn->InputComponent != nullptr)
{
UE_LOG(LogTemp, Warning, TEXT("Hero initing input"));
InitializePlayerInput(Pawn->InputComponent);
}
}
Expand All @@ -159,6 +164,7 @@ void UECRHeroComponent::OnPawnReadyToInitialize()
{
if (UECRCameraComponent* CameraComponent = UECRCameraComponent::FindCameraComponent(Pawn))
{
UE_LOG(LogTemp, Warning, TEXT("Hero initing camera"));
CameraComponent->DetermineCameraModeDelegate.BindUObject(this, &ThisClass::DetermineCameraMode);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ void UECRPawnExtensionComponent::SetupPlayerInputComponent()

bool UECRPawnExtensionComponent::CheckPawnReadyToInitialize()
{
UE_LOG(LogTemp, Warning, TEXT("Checking pawn ready"));
if (bPawnReadyToInitialize)
{
return true;
Expand All @@ -186,6 +187,7 @@ bool UECRPawnExtensionComponent::CheckPawnReadyToInitialize()
// Pawn data is required.
if (!PawnData)
{
UE_LOG(LogTemp, Warning, TEXT("Checking pawn ready failed: no pawn data"));
return false;
}

Expand All @@ -199,6 +201,7 @@ bool UECRPawnExtensionComponent::CheckPawnReadyToInitialize()
// Check for being possessed by a controller.
if (!GetController<AController>())
{
UE_LOG(LogTemp, Warning, TEXT("Checking pawn ready failed: no controller"));
return false;
}
}
Expand All @@ -210,10 +213,13 @@ bool UECRPawnExtensionComponent::CheckPawnReadyToInitialize()
const IECRReadyInterface* Ready = CastChecked<IECRReadyInterface>(InteractableComponent);
if (!Ready->IsPawnComponentReadyToInitialize())
{
UE_LOG(LogTemp, Warning, TEXT("Checking pawn ready failed: one of pawn comps not ready"));
return false;
}
}

UE_LOG(LogTemp, Warning, TEXT("Checking pawn ready success"));

// Pawn is ready to initialize.
bPawnReadyToInitialize = true;
OnPawnReadyToInitialize.Broadcast();
Expand Down
3 changes: 2 additions & 1 deletion Source/ECR/Private/Gameplay/ECRGameMode.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// Copyright Epic Games, Inc. All Rights Reserved.

#include "Gameplay/ECRGameMode.h"

#include "System/ECRLogChannels.h"
#include "GameFramework/PlayerState.h"
#include "Gameplay/Character/ECRCharacter.h"
#include "Gameplay/Character/ECRPawnExtensionComponent.h"
#include "Kismet/GameplayStatics.h"
#include "UObject/ConstructorHelpers.h"

Expand Down
52 changes: 1 addition & 51 deletions Source/ECR/Private/Gameplay/Player/ECRPlayerState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,12 @@
#include "Net/UnrealNetwork.h"
#include "Gameplay/Character/ECRPawnExtensionComponent.h"
#include "Gameplay/GAS/ECRAbilitySystemComponent.h"
#include "Gameplay/GAS/ECRAbilitySet.h"

#include "Gameplay/GAS/Attributes/ECRHealthSet.h"
#include "Gameplay/GAS/Attributes/ECRCombatSet.h"
#include "Gameplay/Character/ECRPawnData.h"
#include "Components/GameFrameworkComponentManager.h"


const FName AECRPlayerState::NAME_ECRAbilityReady("ECRAbilitiesReady");


AECRPlayerState::AECRPlayerState(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
Expand Down Expand Up @@ -50,17 +46,6 @@ void AECRPlayerState::ClientInitialize(AController* C)
}
}


void AECRPlayerState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);

FDoRepLifetimeParams SharedParams;
SharedParams.bIsPushBased = true;

DOREPLIFETIME_WITH_PARAMS_FAST(ThisClass, PawnData, SharedParams);
}

UAbilitySystemComponent* AECRPlayerState::GetAbilitySystemComponent() const
{
return GetECRAbilitySystemComponent();
Expand All @@ -73,38 +58,3 @@ void AECRPlayerState::PostInitializeComponents()
check(AbilitySystemComponent);
AbilitySystemComponent->InitAbilityActorInfo(this, GetPawn());
}

void AECRPlayerState::SetPawnData(const UECRPawnData* InPawnData)
{
check(InPawnData);

if (GetLocalRole() != ROLE_Authority)
{
return;
}

if (PawnData)
{
UE_LOG(LogECR, Error, TEXT("Trying to set PawnData [%s] on player state [%s] that already has valid PawnData [%s]."), *GetNameSafe(InPawnData), *GetNameSafe(this), *GetNameSafe(PawnData));
return;
}

MARK_PROPERTY_DIRTY_FROM_NAME(ThisClass, PawnData, this);
PawnData = InPawnData;

for (const UECRAbilitySet* AbilitySet : PawnData->AbilitySets)
{
if (AbilitySet)
{
AbilitySet->GiveToAbilitySystem(AbilitySystemComponent, nullptr);
}
}

UGameFrameworkComponentManager::SendGameFrameworkComponentExtensionEvent(this, NAME_ECRAbilityReady);

ForceNetUpdate();
}

void AECRPlayerState::OnRep_PawnData()
{
}
28 changes: 21 additions & 7 deletions Source/ECR/Public/Gameplay/Character/ECRCharacter.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class UAbilitySystemComponent;
class UECRPawnExtensionComponent;
class UECRHealthComponent;
class UECRCameraComponent;
class UECRPawnData;
class UECRAbilitySet;


/**
Expand All @@ -29,13 +31,13 @@ struct FECRReplicatedAcceleration
GENERATED_BODY()

UPROPERTY()
uint8 AccelXYRadians = 0; // Direction of XY accel component, quantized to represent [0, 2*pi]
uint8 AccelXYRadians = 0; // Direction of XY accel component, quantized to represent [0, 2*pi]

UPROPERTY()
uint8 AccelXYMagnitude = 0; //Accel rate of XY component, quantized to represent [0, MaxAcceleration]
uint8 AccelXYMagnitude = 0; //Accel rate of XY component, quantized to represent [0, MaxAcceleration]

UPROPERTY()
int8 AccelZ = 0; // Raw Z accel rate component, quantized to represent [-MaxAcceleration, MaxAcceleration]
int8 AccelZ = 0; // Raw Z accel rate component, quantized to represent [-MaxAcceleration, MaxAcceleration]
};


Expand All @@ -47,14 +49,17 @@ struct FECRReplicatedAcceleration
* New behavior should be added via pawn components when possible.
*/
UCLASS(Config = Game, Meta = (ShortTooltip = "The base character pawn class used by this project."))
class AECRCharacter : public ACharacter, public IAbilitySystemInterface, public IGameplayCueInterface, public IGameplayTagAssetInterface
class AECRCharacter : public ACharacter, public IAbilitySystemInterface, public IGameplayCueInterface,
public IGameplayTagAssetInterface
{
GENERATED_BODY()

public:

AECRCharacter(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());

template <class T>
const T* GetPawnData() const { return Cast<T>(PawnData); }

UFUNCTION(BlueprintCallable, Category = "ECR|Character")
AECRPlayerController* GetECRPlayerController() const;

Expand Down Expand Up @@ -82,7 +87,6 @@ class AECRCharacter : public ACharacter, public IAbilitySystemInterface, public
//~End of AActor interface

protected:

virtual void OnAbilitySystemInitialized();
virtual void OnAbilitySystemUninitialized();

Expand Down Expand Up @@ -122,8 +126,9 @@ class AECRCharacter : public ACharacter, public IAbilitySystemInterface, public

virtual bool CanJumpInternal_Implementation() const;

private:
void InitPawnData();

private:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "ECR|Character", Meta = (AllowPrivateAccess = "true"))
UECRPawnExtensionComponent* PawnExtComponent;

Expand All @@ -135,7 +140,16 @@ class AECRCharacter : public ACharacter, public IAbilitySystemInterface, public

UPROPERTY(Transient, ReplicatedUsing = OnRep_ReplicatedAcceleration)
FECRReplicatedAcceleration ReplicatedAcceleration;

static const FName NAME_ECRAbilityReady;

UPROPERTY(ReplicatedUsing = OnRep_PawnData, EditAnywhere, BlueprintReadOnly,
meta=(AllowPrivateAccess="true", ExposeOnSpawn="true"))
const UECRPawnData* PawnData;

private:
UFUNCTION()
void OnRep_PawnData();

UFUNCTION()
void OnRep_ReplicatedAcceleration();
Expand Down
3 changes: 2 additions & 1 deletion Source/ECR/Public/Gameplay/ECRGameMode.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ class AECRGameMode : public AGameMode
/** Storage for display names passed via map parameters */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess = "true"))
TMap<AController*, FString> ControllersToDisplayNames;

protected:
virtual FString InitNewPlayer(APlayerController* NewPlayerController, const FUniqueNetIdRepl& UniqueId,
const FString& Options, const FString& Portal) override;

public:
AECRGameMode();
};

2 comments on commit d3c74be

@scire-feci
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code works great with Lyra for 5.1.1. Thank you so much for this! I thought I had designed myself into a corner by planning a class-based multiplayer game, but this solves it.

One question though - it does seem to break Lyra's AutoRespawn implementation. Did you have to fix that as well?

@JediKnightChan
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, in my game there is no auto respawn, players have to press buttons, "Respawn" to get into menu with the selection of spawn points (default spawns, control points, ...), when they select a point, it spawns them there (spawn Character blueprint, possess it);

Please sign in to comment.