Can't see replicated component in "BeginPlay"?

Hi!

I can’t see my replicated component in “BeginPlay”. I thought “BeginPlay” wasn’t called before all u-properties were replicated initially. This not case though I have discovered.

However I create an actorcomponent like this:

void AMyActor::PreInitializeComponents()
{
	Super::PreInitializeComponents();

	if (Role == ROLE_Authority)
	{
		MyComponent = ConstructObject<UMyComponent>(UMyComponent::StaticClass(), this);
		MyComponent->RegisterComponent();

        ...

}
}

In “BeginPlay” on the client it’s NULL. So now I want to fix so it won’t be null in the “BeginPlay” method.

The AActor’s member “Owner” is always replicated correctly at begin play so I thought it might maybe be possible to send more u-properties. All I find related to replication though is only this:

DOREPLIFETIME( AActor, Owner );

Seems to be a very unexplored and undocumented area. The network documentation overall is very sparse apart from a brief introduction.

I tried to use the following methods:

virtual void OnSerializeNewActor(class FOutBunch& OutBunch)
virtual void OnActorChannelOpen(class FInBunch& InBunch, class UNetConnection* Connection)

But it seems like the method SerializeObject used in FNetBitWriter always will return false? Why? Does this mean you can’t replicate u-objects then?

virtual bool SerializeObject( FArchive& Ar, UClass* Class, UObject*& Obj, FNetworkGUID *OutNetGUID = NULL ) { return false; }

When I tired using it the value was non null at the server but when reading it at the client it was null? I guess the replication failed since SerializeObject doesn’t seems to do anything. Could someone please explain how to get this to work or is it just unsupported?

Thanks in advance!

If I am following this right. You have an ActorComponent you want replicated to the client that is created during PreInitializeComponents. When BeginPlay on the client is called, the actor component is null, correct?

First… (the is your computer plugged in question) Ensure your ActorComponent has bReplicates set to true. You can call SetReplicates(true) immediately after constructing it… or just call that same function in the constructor of your ActorComponent. Then ensure any properties you want replicated are marked as replicated and are passed via DOREPLIFETIME macro function thinggy in the GetLifetimeReplicatedProps function.

Okay with that checked off, I literally just did this same thing. Generally your actor component should only need to initialize on the server. Meaning that the server calls BeginPlay and does some work on it. Then any values that are changed should “replicate” automatically down to the player. This means you should not need to do anything in beginplay on the client to your actor component because it should already have been done on the server.

Further more with out executing a RPC to the server changing the value of your component on the client will not update it on the server and thus your client’s component and the server’s component will be out of sync until the server replicates some value down.

The exception to this is the case where you have spawned an actor on the client (in which case it does not exist on the server).

Hi, thanks for your reply.

Yes, the computer is plugged in i.e. bReplicates = true in the component and in the actor. The actor’s u-property is also marked as replicated. It worked after just one game loop when I ran some debugging instances.

Normally this wouldn’t be a problem but I’m building a custom input solution for the player controller in my example and therefore wants to bind some input to different components. The problem is that this input must be binded on the client side. I wanted some more flexibility and therefore decided to separate some input logic into several components. Thereof the problem. I can also see the problem if there are a lot of tick dependencies since those doesn’t replicate.

Obvious this is somehow possible to achieve since it always works with the owner pointer if set. I can’t see any difference basically when going through the code though which makes me wonder. Not sure how to solve this but hope that clarified the problem somewhat.

Ah I see, so you are trying to directly bind the input component to functions that exist on actor components and this is failing because they are null on the client… Well I honestly don’t know this one, I always bind input to some function directly on my actor but I have played with the idea of binding directly to my components.

You may have to do an OnRep notify for that, or bind to functions directly on your actor that call the functions within your components… I’d love to know if there is another solution to this as well.

Hi again!

I ended up binding the input events to the actor’s methods instead. It is somewhat less flexible but good enough for now at least. I will let the thread be open though in case someone out there knows more about this.

It would be really convenient to be able to know that every replicated component is replicated at the “BeginPlay” event. That would really simplify the initiation when a more custom setup is needed, e.g. involving input binding or tick dependencies setup. Maybe someone from EPIC can the answer to this?