[UE] GameplayTag를 날리면서 발생한 문제, OnRep 함수 안 불림, 컴포넌트 클래스 Replicate
GameplayTag를 매개변수를 던져주고 변수에 값을 복사하여 담아 사용하려고 했다. 하지만 복사한 값을 사용하려고 할 때 문제가 발생했다.
목차
GameplayTag를 날리면서 발생한 문제
문제
GameplayTag를 매개변수를 던져주고 변수에 값을 복사하여 담아 사용하려고 했다.
하지만 복사한 값을 사용하려고 할 때 문제가 발생했다.
문제가 발생한 부분 코드
키 입력 후 GameplayTag를 매개변수로 넘기는 부분
void UXZPawnExtensionComponent::Input_EquipSlot2(const FInputActionValue& InputActionValue)
{
if (GetXZCharacter() && GetXZCharacter()->GetWeaponComponent())
{
FGameplayTag Tag = FXZTags::GetXZTags().Weapon_Projectile_Rifle;
GetXZCharacter()->GetWeaponComponent()->EquipWeapon(Tag);
}
}
문제가 발생하는 부분
#pragma once
#include "CoreMinimal.h"
#include "GameplayTagContainer.h"
#include "Components/ActorComponent.h"
#include "ProjectXZ/GameplayTag/XZGameplayTags.h"
#include "XZWeaponComponent.generated.h"
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class PROJECTXZ_API UXZWeaponComponent : public UActorComponent
{
GENERATED_BODY()
public:
UXZWeaponComponent();
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
void EquipWeapon(const FGameplayTag& InTag);
UFUNCTION(Server, Reliable)
void Server_EquipWeapon(const FGameplayTag& InTag);
UFUNCTION(NetMulticast, Reliable)
void Multicast_EquipWeapon(const FGameplayTag& InTag);
UPROPERTY(ReplicatedUsing = OnRep_EquippedChanged)
FGameplayTag EquippedWeaponTag = FXZTags::GetXZTags().Fist;
};
#include "XZWeaponComponent.h"
...
UXZWeaponComponent::UXZWeaponComponent()
{
PrimaryComponentTick.bCanEverTick = true;
}
void UXZWeaponComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(UXZWeaponComponent, EquippedWeaponTag);
}
void UXZWeaponComponent::EquipWeapon(const FGameplayTag& InTag)
{
EquippedWeaponTag = InTag;
Server_EquipWeapon(EquippedWeaponTag);
}
void UXZWeaponComponent::OnRep_EquippedChanged()
{
Server_EquipWeapon(EquippedWeaponTag);
}
void UXZWeaponComponent::Server_EquipWeapon_Implementation(const FGameplayTag& InTag)
{
Multicast_EquipWeapon(InTag);
}
void UXZWeaponComponent::Multicast_EquipWeapon_Implementation(const FGameplayTag& InTag)
{
// 슬롯에 등록된 무기의 GameplayTag를 InTag로 가져옴
if (UXZWeaponData** FoundData = Datas.Find(EquippedWeaponTag))
{
if (*FoundData)
{
if (Datas[EquippedWeaponTag]->GetEquipment()->Equip()) // 무기장착 O
{
}
else // 무기장착 X (= Unequip 수행한 경우)
{
Datas[EquippedWeaponTag]->GetEquipment()->Unequip();
EquippedWeaponTag = FXZTags::GetXZTags().Fist;
}
}
}
}
코드 고쳐야지.. 되도록 Multicast는...
처음 테스트한 부분
문제가 발생한 부분(Breaking Point가 걸린 부분)에 업데이트한 변수값(= EquippedWeaponTag)이 아닌 매개변수 값으로 넘겨주었다.
이렇게 하니 정상적으로 동작하였다.
문제가 되는 코드
void UXZWeaponComponent::EquipWeapon(const FGameplayTag& InTag)
{
EquippedWeaponTag = InTag;
Server_EquipWeapon(EquippedWeaponTag);
}
제대로 동작하는 코드
void UXZWeaponComponent::EquipWeapon(const FGameplayTag& InTag)
{
EquippedWeaponTag = InTag;
Server_EquipWeapon(InTag);
}
하지만 이 방식은 내가 원하던 방식이 아니었다.
일단 원인을 파악했다.
EquippedWeaponTag 변수값이 멀티플레이어 환경에서 업데이트 되지 않는것이었다. 그래서 변수가 변경되었을때 호출되는 OnRep_EquippedChanged() 함수가 호출되지 않았던 것이다.
원인 분석 및 해결 방안 (왜 변수가 업데이트가 되지 않는가?)
1. 첫번째 실수 - 변수값을 변경하는 부분은 서버!여야 한다.
FGameplayTag EquippedWeaponTag를 변경한 부분이 클라이언트 부분이었다.
UPROPERTY(Replicated) 나 UPROPERTY(ReplicatedUsing= )으로 선언한 변수들은 서버에서 변경되어야 한다.
그래서 태그가 변경되는 위치를 옮겼다.
Before
void UXZWeaponComponent::EquipWeapon(const FGameplayTag& InTag)
{
EquippedWeaponTag = InTag;
Server_EquipWeapon(EquippedWeaponTag);
}
After
void UXZWeaponComponent::EquipWeapon(const FGameplayTag& InTag)
{
Server_EquipWeapon(InTag);
}
void UXZWeaponComponent::Server_EquipWeapon_Implementation(const FGameplayTag& InTag)
{
EquippedWeaponTag = InTag;
...
}
2. 두번째 실수 - 작업하는 클래스의 Replicate 설정을 키자!
작업하고 있는 클래스의 Replicates 가 켜지지 않았다.
ActorComponent 상속 클래스의 Replicates은 bReplicates = true가 아니라 컴포넌트 버젼의 변수를 켜줘야 한다.
아래를 보면..
BP: Component Replicates 를 true 체크해줘야 한다.
C++: 코드로 설정하려면 다음과 같다.
- SetIsReplicatedByDefault(true) 로 설정해야 한다.
※ 참고) SetIsReplicated(true) 도 사용할 수 있지만 생성자 위치에서 선언하는거면 SetIsReplicatedByDefault(true) 를 사용하는게 좋다.
'⭐ Unreal Engine > UE Debugging Log' 카테고리의 다른 글
[UE] Unreal Insights 엔진 코드에서 생성하기 (0) | 2024.10.01 |
---|---|
[UE] Build.cs에 PublicDependencyModuleNames 추가해도 컴파일이 되지 않음 (0) | 2024.09.20 |
[UE] 입력 BindAction 템플릿 함수에서 발생한 문제 (0) | 2024.07.27 |
[UE] SpawnActor 시점에 에러 발생 (0) | 2024.07.26 |
[UE] 몽타주 생성 시 A-pose 하는 문제 (0) | 2024.07.26 |
댓글
이 글 공유하기
다른 글
-
[UE] Unreal Insights 엔진 코드에서 생성하기
[UE] Unreal Insights 엔진 코드에서 생성하기
2024.10.01 -
[UE] Build.cs에 PublicDependencyModuleNames 추가해도 컴파일이 되지 않음
[UE] Build.cs에 PublicDependencyModuleNames 추가해도 컴파일이 되지 않음
2024.09.20 -
[UE] 입력 BindAction 템플릿 함수에서 발생한 문제
[UE] 입력 BindAction 템플릿 함수에서 발생한 문제
2024.07.27 -
[UE] SpawnActor 시점에 에러 발생
[UE] SpawnActor 시점에 에러 발생
2024.07.26