How to go about replicating variables inside UObject's BP child class?

im a bit stuck on how to make a UObject replicate its variables from server to client, im very new to c++ and just started learning it after getting the hang onf the engine in genereal by using BP, what im trying to do now is basically have a weapon object (not using actors because it doesnt need a visual representation, as its the item that stores data about the weapon, such as ammo and reload animations) replicate how much ammo that weapon has to other clients, i have the UObject already set up to be replicated through other actors, now i need to know how to replicate variables from the UObject’s blueprint child class.

Any help would be greatly appreciated since i am stuck on this for quite a while now

UObject .h

#pragma once

#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "WeaponObject.generated.h"

/**
 * 
 */
UCLASS(Blueprintable)
class SHOOTER_PROJECT_API UWeaponObject : public UObject
{
	GENERATED_BODY()

public:

	virtual bool IsSupportedForNetworking() const override { return true; };

	void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>&OutLifetimeProps);


};

UObject .cpp

#include "WeaponObject.h"
#include "Net/UnrealNetwork.h"


void UWeaponObject::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps)
{

	Super::GetLifetimeReplicatedProps(OutLifetimeProps);

	UBlueprintGeneratedClass* BPClass = Cast<UBlueprintGeneratedClass>(GetClass());
	if (BPClass) BPClass->GetLifetimeBlueprintReplicationList(OutLifetimeProps);

}

I don’t think I fully understand what the issue is here, but I will do my best to answer this.

1.

now i need to know how to replicate variables from the UObject’s blueprint child class.

I’m not sure what you mean by this. Are you making sure that each variable is set as Replicated in the class? I haven’t used a raw UObject in the editor lately but I’m sure that variable properties still have the option within Blueprints to be replicated.

If not, do you mean that you are trying to replicate these values and they’re just not getitng sent between client and server? If so, you’ll have to replicate them manually in C++ through the owning actor’s class (which I pray isn’t a generic AActor and is a proper class, like AWeaponActor or something), or - and I have not tested this but it seems it would work too - there should be a bReplicateUsingRegisteredSubobjectsList property somewhere in your parent actor/component.

If you do it manually, this is an example of where I did such a thing for an action system I wrote (which is somewhat similar to what you’re doing, a weapon system, I suppose).

In my action component…

bool UConnActionComponent::ReplicateSubobjects(UActorChannel* Channel, FOutBunch* Bunch, FReplicationFlags* RepFlags)
{
	bool bUpdatesMade = Super::ReplicateSubobjects(Channel, Bunch, RepFlags);

	for(UConnAction* LocAction : Actions) // for your case, UConnAction = UWeaponObject, or whatever you're trying to do
	{
		if(UConnGameplayStatics::VerifyObjWithMsg(LocAction))
		{
			bUpdatesMade |= Channel->ReplicateSubobject(LocAction, *Bunch, *RepFlags);
		}
	}

	return bUpdatesMade;
}

If the issue you are having is indeed that you are trying to replicate your variables but they’re not getting sent, you may have to try this. I assume your weapon OBJECTS are being owned by some kind of weapon ACTOR or a weapon inventory COMPONENT, so you’d drop this code in the actor/component that will typically be the owner of your weapon object, and then adapt it to your needs, which hopefully would not be too difficult.

With that said, that bReplicateUsingRegisteredSubobjectsList property is looking pretty good too. I’ve never tried it because I learned networking from Tom Looman’s course and he did it manually as shown above, but maybe it does exactly that? I can’t be sure but the name suggests it.

2. Have you considered using Structs instead? I don’t know enough about how your project’s architecture is set up, but theoretically you could make an FStruct containing all commonly shared components of your weapons (such as the ammo, damage, reload anims, etc). I would even just pack that struct into the weapon actor class itself (I assume there is one to serve as the visual representation for the weapon) because it may be plenty usable in your inventory. Like I said though, I don’t know too much about your project’s architecture.

Hello! Thank you very much for your reply, yes i do indeed have a AWeaponActor class that replicates the UWeaponObject

WeaponActor.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "WeaponActor.generated.h"

UCLASS()
class SHOOTER_PROJECT_API AWeaponActor : public AActor
{
	GENERATED_BODY()
	
public:

	AWeaponActor();

	virtual bool ReplicateSubobjects(class UActorChannel* Channel, class FOutBunch* Bunch, FReplicationFlags* RepFlags) override;

	void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;

	virtual void BeginPlay();

	void Tick(float DeltaTime);

	UPROPERTY(Replicated, BlueprintReadWrite, EditAnywhere, Category = "Default", meta = (ExposeOnSpawn = "true"))
		class UWeaponObject* WeaponObject;
};

WeaponActor.cpp

#include "WeaponActor.h"
#include "Net/UnrealNetwork.h"
#include "Engine/World.h"
#include "Engine/ActorChannel.h"
#include "C:/MY STUFF/UE PROJECTOS/Shooter_Project/Source/Shooter_Project/WeaponObject.h"

AWeaponActor::AWeaponActor()
{
	//set replicates
	bReplicates = true;
	//replication radius
	NetCullDistanceSquared = 99999;
	//replication frequency 
	NetUpdateFrequency = 1.f;
	//tick enabled
	PrimaryActorTick.bCanEverTick = true;
}

bool AWeaponActor::ReplicateSubobjects(UActorChannel* Channel, FOutBunch* Bunch, FReplicationFlags* RepFlags)
{
	bool WroteSomething = Super::ReplicateSubobjects(Channel, Bunch, RepFlags);

	// replicate the object
	if (WeaponObject) WroteSomething |= Channel->ReplicateSubobject(WeaponObject, *Bunch, *RepFlags);

	return WroteSomething;
}

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

	//mark the reference to be replicated
	DOREPLIFETIME(AWeaponActor, WeaponObject);
}

// Called when the game starts or when spawned
void AWeaponActor::BeginPlay()
{
	Super::BeginPlay();
	
}

// Called every frame
void AWeaponActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

what im trying to do is mark the variables created in a blueprint child class for replication since i read that they are not marked for replication by default.
bpclass

And yes i have set all of them to replicate in the bp class, but they dont seem to get updated on client side when set on the server, is it possible to mark these variables created in the BP class for replication, or do i have to create them in the c++ class and do it there?

I really want to refrain from using structs in this case because im trying to learn more about UObjects and how to use them.

Okay i figured it out, there was a mistake in my code, one of the functions in the header and cpp files didnt have a “const” at the end

.h
void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>&OutLifetimeProps) const override;
.cpp
void UWeaponObject::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const

not exactly sure how, but it seemed to fix everything, and now the variables are getting replicated propperly

1 Like