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:
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.
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.
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.