일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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
- 게임개발
- 유니티
- CTF
- MAC
- Multiplay
- gameplay effect
- local prediction
- 게임 개발
- attribute
- map design
- network object pooling
- gameplay ability system
- photon fusion2
- os
- nanite
- UI
- Aegis
- stride
- 언리얼엔진
- rpc
- gas
- 언리얼 엔진
- 보안
- Replication
- listen server
- unity
- ability task
- Unreal Engine
- animation
- gameplay tag
Archives
- Today
- Total
Replicated
[Drag Down] 기본세팅 #2 : Attribute, PlayerState 본문
Attribute
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "AttributeSet.h"
#include "AbilitySystemComponent.h"
#include "DDAttributeSet.generated.h"
#define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)
/**
*
*/
UCLASS()
class DRAGDOWN_API UDDAttributeSet : public UAttributeSet
{
GENERATED_BODY()
public:
UDDAttributeSet();
ATTRIBUTE_ACCESSORS(UDDAttributeSet, Stamina);
ATTRIBUTE_ACCESSORS(UDDAttributeSet, MaxStamina);
// Meta Attribute
ATTRIBUTE_ACCESSORS(UDDAttributeSet, Damage);
virtual void PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue) override;
//virtual void PostAttributeChange(const FGameplayAttribute& Attribute, float OldValue, float NewValue) override;
//virtual bool PreGameplayEffectExecute(struct FGameplayEffectModCallbackData& Data) override;
virtual void PostGameplayEffectExecute(const struct FGameplayEffectModCallbackData& Data) override;
protected:
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
UPROPERTY(BlueprintReadOnly, Category = "Stamina", ReplicatedUsing = OnRep_Stamina, Meta = (AllowPrivateAccess = true))
FGameplayAttributeData Stamina;
UPROPERTY(BlueprintReadOnly, Category = "Stamina", ReplicatedUsing = OnRep_MaxStamina, Meta = (AllowPrivateAccess = true))
FGameplayAttributeData MaxStamina;
UPROPERTY(BlueprintReadOnly, Category = "Damage", Meta = (AllowPrivateAccess = true))
FGameplayAttributeData Damage;
UFUNCTION()
void OnRep_Stamina(const FGameplayAttributeData& OldStamina);
UFUNCTION()
void OnRep_MaxStamina(const FGameplayAttributeData& OldMaxStamina);
};
일단 Stamina와 MaxStamina라는 어트리뷰트를 만들고, Damage는 메타 어트리뷰트로 사용한다.
Stamina와 MaxStamina는 리플리케이션 처리 해준다.
// Fill out your copyright notice in the Description page of Project Settings.
#include "Attribute/DDAttributeSet.h"
#include "GameplayEffectExtension.h"
#include "Net/UnrealNetwork.h"
#include "DragDown.h"
UDDAttributeSet::UDDAttributeSet() : MaxStamina(100.0f), Damage(0.0f)
{
InitStamina(GetMaxStamina());
}
void UDDAttributeSet::PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue)
{
if (Attribute == GetDamageAttribute())
{
NewValue = NewValue < 0.0f ? 0.0f : NewValue;
}
}
void UDDAttributeSet::PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data)
{
Super::PostGameplayEffectExecute(Data);
float MinimumStamina = 0.0f;
if (Data.EvaluatedData.Attribute == GetStaminaAttribute())
{
SetStamina(FMath::Clamp(GetStamina(), MinimumStamina, GetMaxStamina()));
UE_LOG(LogDD, Warning, TEXT("Direct Health Access : %f"), GetStamina());
}
else if (Data.EvaluatedData.Attribute == GetDamageAttribute())
{
SetStamina(FMath::Clamp(GetStamina() - GetDamage(), MinimumStamina, GetMaxStamina()));
UE_LOG(LogDD, Log, TEXT("[NetMode : %d] Damage Detected : %f | Now Energy : %f"), GetWorld()->GetNetMode(), GetDamage(), GetStamina());
}
}
void UDDAttributeSet::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION_NOTIFY(UDDAttributeSet, Stamina, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UDDAttributeSet, MaxStamina, COND_None, REPNOTIFY_Always);
}
void UDDAttributeSet::OnRep_Stamina(const FGameplayAttributeData& OldStamina)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UDDAttributeSet, Stamina, OldStamina);
}
void UDDAttributeSet::OnRep_MaxStamina(const FGameplayAttributeData& OldMaxStamina)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UDDAttributeSet, MaxStamina, OldMaxStamina);
}
PreAttributeChange에서는 이펙트 적용 전 값을 검사한다.
Stamina는 0 미만이 될 수 없다.
PostGameplayEffectExecute에선 다시 한 번 스테미나를 검사(굳이 안해도 되긴 함)
그리고 대미지가 들어온 경우 스테미나를 깎아줌 (0미만 불가, 100 초과 불가)
카메라 흔들기 같은 효과가 필요한 경우 PostGameplayEffectExecute Damage 변경 부분에 처리해주면 됨
* 대미지를 받으면 카메라 흔들기
GetLifetimeReplicatedProps에서 Stamina와 MaxStamina 동기화 처리
OnRep_Stamina와 OnRep_MaxStamina에서 GAMEPLAYATTRIBUTE_REPNOTIFY를 해주는데,
이걸 안해주면 추후 값 리플리케이션에 의한 UI 업데이트가 제대로 안된다. 필수적으로 해줘야 한다.
Player State
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PlayerState.h"
#include "AbilitySystemInterface.h"
#include "DDPlayerState.generated.h"
/**
*
*/
UCLASS()
class DRAGDOWN_API ADDPlayerState : public APlayerState, public IAbilitySystemInterface
{
GENERATED_BODY()
public:
ADDPlayerState();
virtual class UAbilitySystemComponent* GetAbilitySystemComponent() const override;
protected:
UPROPERTY(EditAnywhere, Category = GAS)
TObjectPtr<class UAbilitySystemComponent> ASC;
UPROPERTY()
TObjectPtr<class UDDAttributeSet> AttributeSet;
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "Player/DDPlayerState.h"
#include "AbilitySystemComponent.h"
#include "Attribute/DDAttributeSet.h"
ADDPlayerState::ADDPlayerState()
{
ASC = CreateDefaultSubobject<UAbilitySystemComponent>(TEXT("ASC"));
ASC->SetIsReplicated(true);
AttributeSet = CreateDefaultSubobject<UDDAttributeSet>(TEXT("AttributeSet"));
}
UAbilitySystemComponent* ADDPlayerState::GetAbilitySystemComponent() const
{
return ASC;
}
상태 관리 등을 위해 PlayerState에서 ASC와 AttributeSet을 관리
* AttributeSet을 ASC에 등록시키지 않은 이유?
UAbilitySystemComponent::InitializeComponent()에 같은 오브젝트에 붙어있는 어트리뷰트 찾아서 알아서 붙여줌
내가 안해줘도 알아서 해주니까 안해도 됨
'언리얼 엔진 > Drag Down (캡스톤 디자인)' 카테고리의 다른 글
[Drag Down] 애니메이션 애셋 (0) | 2025.03.25 |
---|---|
[Drag Down] Idle, Locomotion, Jump (0) | 2025.03.25 |
[Drag Down] 기본 세팅 #1 : Character Base, Player (0) | 2025.03.19 |
[Drag Down] Collision Setting (0) | 2025.03.19 |
[Drag Down] 프로젝트 개요 (0) | 2025.03.12 |