Components and component children, required components, etc

I’ve ran into a few major problems with components which so far haven’t required crazy refactors, but ideally I would like to have the issues solved. Components so far in UE4 are far better supported than in UE3, but still don’t seem to be first order objects as of yet.
This post has a few independent questions related to components, but figured I’d group them together for a better searchable knowledge dump if they do get answered.

The first issue is how ActorComponents with member/Children ActorComponents are serialized to packages and across the network.
I have an answerhub question for the main basis of this question: https://answers.unrealengine.com/questions/82617/is-it-possible-for-actorcomponents-to-have-member.html, but I will elaborate further here.

Component A and B are both set to replicate along with their Actor Owner.
Component A has a TArray of Component B. Component B is marked Edit inline only and the TArray is Edit inline. This allowed me to create an instances of B or its derived types inside the TArray at editor time. Component B has a strict dependency on Component A and has no reason to live as a sibling of A or other components.
In singleplayer this works fine I have no warnings, errors, etc, but in multiplayer I run into problems.
Component B’s outer is component A and not the actor they are a part of. When the B objects are serialized into the bunch I often run into problems.
Sometimes the client has multiple instances of B such that they are out of sync with the server, sometimes it crashes or sometimes it works due to randomly finding the right instance.
The bunch appears to be written correctly in the server, but is not received well.

The warnings I typically receive:

LogPackageName: SearchForPackageOnDisk took 0.068s to resolve Component B
LogUObjectGlobals:Warning: LoadPackage can’t find package ComponentB_#.
LogNetPackageMap:Warning: Unable to resolve static NetGUID <185> from Path: ComponentB_#
LogNetPackageMap:Warning: InternalLoadObject unable to resolve reference from NetGUID <185> (received full path: 1) via:

UPackageMapClient::ReceiveNetGUIDBunch
UPackageMapClient::InternalLoadObject
UPackageMapClient::InternalLoadObjectPath
UPackageMapClient::NetGUIDAssign
UPackage* LoadPackage(

Currently I am not doing anything custom to an actor channel or overriding ReplicateSubobject. I will do so if its required for this support, but there is little documentation explaining the process or the typical use case.
Component B is only a component to support RPCs and getreplicatedprops.

Next problem:
If Component A has a regular UProperty ActorComponent pointer that is not edit inline, I would like to be able to point it to instances of that component class on the shared parent actor at editor time via a dropdown or something similar.
This feature seems quite useful and odd to not be supported. I work around this by modifying the construction script for each actor to initialize the correct reference, but would much prefer base actor engine support. I might end up adding this to the engine at a later date.
The answerhub question for this: https://answers.unrealengine.com/questions/73930/a-type-b-component-has-a-pointer-to-another-siblin.html.

Next:
If Actor A had two instances of Component B each of which have an instance of component C. It appears that the uasset serialization does not work correctly for this situation. The second instance of Component C in in the second instance of Component B points to the first instance of Component C.
My coworker ran into this issue. This situation forces us to avoid this particular Actor and component structure.

Next minor issue:
Epic has no concept of required components on an actor.
I’ve sort of supported this by having a TArray< TSubclassOf<class UActorComponent> on a specific actor and then I loop through them and check for an instance on the owning actors blueprint, if they don’t exist then I make a USCS_Node and add them to the blueprint at construction time.
This code is only on one actor for now and could be moved to the base AActor. On other actors or for certain components I can throw a map error, but I can’t throw a blueprint compiler error or disable saving without making a custom details panel for each component afaik. I imagine that
would require modifying the base property editor and the blueprint compiler, which is doable, but not desired.
This is not super important, but would be nice.
Answerhub question for this: https://answers.unrealengine.com/questions/72757/how-to-support-component-dependencyrequired-compon.html.

Lastly, the engine currently does not allow changing the type or simply modifying native or inherited TSubObject ptrs on an actor. Is there any plans to change this? I imagine this is set in stone for a variety of reasons, but this doesn’t allow for a abstract component pointer ref in a base actor and derived actors having different instances of that abstract component class natively or by default.

Thanks in advance.

For issue #1 it appears the WIP GameplayAbilities module has a similar architecture to what I was attempting to do with Component A and Component B.

In order for Component A to successfully replicate an array of base UObject types it looks like the following steps are needed:

  • Create my new UObject Derived class I’ll call BType for now (replacement for Component B).
  • Implement IsSupportedForNetworking in BType
  • Implement GetFunctionCallspace in BType
  • Implement CallRemoteFunction in Btype so RPCs are supported with the proper NetDriver for BType
  • Implement ReplicateSubobjects in Component A and loop over my array of BType calling ReplicateSubObject on the passed in Actor Channel with each instance of BType
  • Implement GetLifetimeReplicatedProps in Component A and rep the respective array BType

It would be great if someone with experience on replicating and using RPCs on a non Actor or ActorComponent could verify that these are the only steps needed.

I also wouldn’t mind my other issues being read over.

Hello, Dzeligman

Sorry for disturbing you with that old thread, but could you please share more details on replicating subobjects?

I’ve ran into a problem, seems the subobjects has no propper serialization (at least in my case - subobjects->subobject), so it will reset all the values to default ones during the replication updates, here is an AH post with my code:

P.S. Is there any progress on using sub components for networking on new engine builds? Maybe it’s better to move all my code to the component base?

Thanks in advance!

Okay, seems it was not a replication problem, but anyway I’ve replaced the parent class from UObject to UActorComponent, which spawns runtime.
At the moment replication (ComponentA->ComponentB) works great.