일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- ability task
- 게임 개발
- attribute
- MAC
- unity
- UI
- 언리얼 엔진
- gas
- gameplay effect
- local prediction
- map design
- network object pooling
- CTF
- Aegis
- 보안
- os
- gameplay ability system
- gameplay tag
- nanite
- 유니티
- Multiplay
- animation
- rpc
- 언리얼엔진
- Replication
- stride
- 게임개발
- photon fusion2
- listen server
- Unreal Engine
Archives
- Today
- Total
Replicated
[Drag Down] GAS관리 Actor Component로 분리 본문
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "AbilitySystemInterface.h"
#include "DDGASManagerComponent.generated.h"
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class DRAGDOWN_API UDDGASManagerComponent : public UActorComponent, public IAbilitySystemInterface
{
GENERATED_BODY()
public:
UDDGASManagerComponent();
virtual class UAbilitySystemComponent* GetAbilitySystemComponent() const override;
void SetASC();
void SetGASAbilities();
void SetupGASInputComponent();
protected:
// Input Pressed RPC **************************************
void GASInputPressed(int32 InputId);
UFUNCTION(Server, Reliable)
void ServerGASInputPressed(int32 InputId);
void HandleGASInputPressed(int32 InputId);
// ********************************************************
// Input Released RPC *************************************
void GASInputReleased(int32 InputId);
UFUNCTION(Server, Reliable)
void ServerGASInputReleased(int32 InputId);
void HandleGASInputReleased(int32 InputId);
// ********************************************************
UPROPERTY(EditAnywhere, Category = GAS)
TObjectPtr<class UAbilitySystemComponent> ASC;
UPROPERTY(EditAnywhere, Category = GAS)
TArray< TSubclassOf<class UGameplayAbility> > StartAbilities;
UPROPERTY(EditAnywhere, Category = GAS)
TMap< int32, TSubclassOf<class UGameplayAbility> > StartInputAbilities;
// Action
protected:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, Meta = (AllowPrivateAccess = "true"))
TObjectPtr<class UInputAction> PushingAction;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, Meta = (AllowPrivateAccess = "true"))
TObjectPtr<class UInputAction> DodgeAction;
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "ActorComponent/DDGASManagerComponent.h"
#include "AbilitySystemComponent.h"
#include "EnhancedInputSubsystems.h"
#include "EnhancedInputComponent.h"
#include "Player/DDPlayerState.h"
#include "Character/DDCharacterBase.h"
#include "DragDown.h"
// Sets default values for this component's properties
UDDGASManagerComponent::UDDGASManagerComponent()
{
SetIsReplicatedByDefault(true);
ASC = nullptr;
static ConstructorHelpers::FObjectFinder<UInputAction> InputActionPushingRef(TEXT("/Script/EnhancedInput.InputAction'/Game/Input/Actions/IA_Pushing.IA_Pushing'"));
if (nullptr != InputActionPushingRef.Object)
{
PushingAction = InputActionPushingRef.Object;
}
static ConstructorHelpers::FObjectFinder<UInputAction> InputActionDodgeRef(TEXT("/Script/EnhancedInput.InputAction'/Game/Input/Actions/IA_Dodge.IA_Dodge'"));
if (nullptr != InputActionDodgeRef.Object)
{
DodgeAction = InputActionDodgeRef.Object;
}
}
UAbilitySystemComponent* UDDGASManagerComponent::GetAbilitySystemComponent() const
{
return ASC;
}
void UDDGASManagerComponent::SetASC()
{
if (ASC) return;
AActor* Owner = GetOwner();
ensure(Cast<APawn>(Owner));
ADDPlayerState* CSPS = Cast<APawn>(Owner)->GetPlayerState<ADDPlayerState>();
if (CSPS)
{
ASC = CSPS->GetAbilitySystemComponent();
ASC->InitAbilityActorInfo(CSPS, Owner);
ASC->ReplicationMode = EGameplayEffectReplicationMode::Mixed;
UE_LOG(LogDD, Log, TEXT("*** [NetMode : %d] SetASC, %s, %s"), GetWorld()->GetNetMode(), *GetName(), *Cast<APawn>(Owner)->GetPlayerState()->GetName());
}
else
{
UE_LOG(LogDD, Log, TEXT("[NetMode %d] SetASC - ASC Not Found"), GetWorld()->GetNetMode());
}
}
void UDDGASManagerComponent::SetGASAbilities()
{
if ( ASC && GetOwner()->HasAuthority() )
{
for (const auto& StartAbility : StartAbilities)
{
FGameplayAbilitySpec StartSpec(StartAbility);
ASC->GiveAbility(StartSpec);
}
for (const auto& StartInputAbility : StartInputAbilities)
{
FGameplayAbilitySpec StartSpec(StartInputAbility.Value);
StartSpec.InputID = StartInputAbility.Key;
ASC->GiveAbility(StartSpec);
}
}
}
void UDDGASManagerComponent::SetupGASInputComponent()
{
if (IsValid(GetOwner()->InputComponent))
{
UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(GetOwner()->InputComponent);
//추가 gas 액션
EnhancedInputComponent->BindAction(PushingAction, ETriggerEvent::Triggered, this, &UDDGASManagerComponent::GASInputPressed, 1);
EnhancedInputComponent->BindAction(PushingAction, ETriggerEvent::Completed, this, &UDDGASManagerComponent::GASInputReleased, 1);
EnhancedInputComponent->BindAction(DodgeAction, ETriggerEvent::Triggered, this, &UDDGASManagerComponent::GASInputPressed, 2);
EnhancedInputComponent->BindAction(DodgeAction, ETriggerEvent::Completed, this, &UDDGASManagerComponent::GASInputReleased, 2);
UE_LOG(LogDD, Log, TEXT("SetupGASInputComponent Succeed"));
}
else if (!IsValid(ASC))
{
UE_LOG(LogDD, Log, TEXT("Invalid ASC"));
}
else
{
UE_LOG(LogDD, Log, TEXT("Invalid InputComponent"));
}
}
void UDDGASManagerComponent::GASInputPressed(int32 InputId)
{
ensure(Cast<ADDCharacterBase>(GetOwner()));
if ( !Cast<ADDCharacterBase>(GetOwner())->GetActionEnabled() ) return;
HandleGASInputPressed(InputId);
if (!GetOwner()->HasAuthority())
{
ServerGASInputPressed(InputId);
}
}
void UDDGASManagerComponent::HandleGASInputPressed(int32 InputId)
{
if (!ASC)
{
return;
}
FGameplayAbilitySpec* Spec = ASC->FindAbilitySpecFromInputID(InputId);
if (Spec)
{
if (Spec->InputPressed) return;
UE_LOG(LogDD, Log, TEXT("InputPressed"));
Spec->InputPressed = true;
if (Spec->IsActive())
{
ASC->AbilitySpecInputPressed(*Spec);
}
else
{
ASC->TryActivateAbility(Spec->Handle, true);
}
}
}
void UDDGASManagerComponent::GASInputReleased(int32 InputId)
{
HandleGASInputReleased(InputId);
if (!GetOwner()->HasAuthority())
{
ServerGASInputReleased(InputId);
}
}
void UDDGASManagerComponent::HandleGASInputReleased(int32 InputId)
{
if (!ASC)
{
return;
}
FGameplayAbilitySpec* Spec = ASC->FindAbilitySpecFromInputID(InputId);
if (Spec)
{
Spec->InputPressed = false;
if (Spec->IsActive())
{
ASC->AbilitySpecInputReleased(*Spec);
}
}
}
void UDDGASManagerComponent::ServerGASInputPressed_Implementation(int32 InputId)
{
if (GetOwner()->HasAuthority())
{
HandleGASInputPressed(InputId);
}
}
void UDDGASManagerComponent::ServerGASInputReleased_Implementation(int32 InputId)
{
if ( GetOwner()->HasAuthority() )
{
HandleGASInputReleased(InputId);
}
}
기존 캐릭터의 GAS 구조를 분리했다
이제 캐릭터는 ASC조차 가지지 않는다!
(이제 캐릭터에서 Ability System Blueprint로 가져오는 건 불가능, 캐릭터에 IAbilitySystemComponent의 GetAbilitySystemComponent 있어야 됨)
void ADDCharacterPlayer::PossessedBy(AController* NewController)
{
Super::PossessedBy(NewController);
GASManagerComponent->SetASC();
GASManagerComponent->SetGASAbilities();
BuffManagerComponent->Initailize();
}
void ADDCharacterPlayer::OnRep_PlayerState()
{
Super::OnRep_PlayerState();
GASManagerComponent->SetASC();
BuffManagerComponent->Initailize();
}
초기화는 기존 방식에서 함수 콜만 해주자
'언리얼 엔진 > Drag Down (캡스톤 디자인)' 카테고리의 다른 글
** [Drag Down] Unreal 5.5 DLSS C++ 설정해주기 ** (0) | 2025.04.30 |
---|---|
[Drag Down] Data-Dirven 설계 (2) | 2025.04.30 |
** [Drag Down] Animation Local Prediction + RPC ** (0) | 2025.04.30 |
[Drag Down] 그래픽, 디스플레이, 사운드 메뉴 (0) | 2025.04.30 |
** [Drag Down] SetRelativeLocation Problem in Multiplay Runtime 덮어써짐 문제 ** (0) | 2025.04.30 |