[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
댓글을 사용할 수 없습니다.