I’ve been trying to break an ACharacter based class down into several UActorComponent based classes contained within an ACharacter class in order to reduce redundancy and simplify adding new features to the character class. Several of these custom components contain pointers to other components, such as SphereComponents and SceneComponents.
I thought this was OK, since the documentation for components mentions that a car actor might have separate components for its doors and tires. However, the custom components are behaving oddly, and I have described their behavior here. A reply to my question suggested using true for the argument bTransient might fix this problem. However, since doing so, I am getting this error:
Assertion failed: SubobjectOuter [File:C:\UnrealEngineSourceBuilds\UnrealEngine-4.10.4-release\Engine\Source\Runtime\CoreUObject\Private\UObject\CoreNative.cpp] [Line: 162]
No corresponding destination object found for 'ArmComponent /Game/Blueprints/Characters/ModularCharacter_BP.Default__ModularCharacter_BP_C:RightArm' while attempting to instance component 'SphereComponent /Game/Blueprints/Characters/ModularCharacter_BP.Default__ModularCharacter_BP_C:RightArm.SphereComponent_0'
Which leads me to believe that what I am trying to do isn’t possible. However, I found more information in the documentation suggesting that the earlier behavior I mentioned could be due to the fact that Components are only instanced from within an actor, and I thought that applying this property to my subobjects might fix the problem. However, my game still crashes when trying to CreateDefaultSubobject when bTransient is set to true. Even after removing “true” from all of my CreateDefaultSubobject calls, I still get the error. So is what I am trying to do even possible? If you need more information, please let me know and I would be happy to provide what I can.
EDIT: For clarification, the hierarchy is that the Character contains a custom component called ArmComponent, this component contains 2 sphere components which are constructed during the construction of ArmComponent, then attached to a bone on the mesh of the Character class. They construct fine, but by the time TickComponent is reached, one of the things I have described above or in a comment below has happened. Is it possible to have a subcomponent of a component which is not attached to said component without this happening?
Ok so I missed a few bTransient = true arguments, and after removing those the game is no longer crashing when loading the Character. Not sure if the Instanced Property fixed the issue I was having though, so I will report back when I know.
Since updating the bTransient = true arguments, I am no longer having the issue where selecting one subcomponent in the components list highlights both of the components in the viewport. It used to be that if I hovered over one “Fist” that both of the SphereComponents would be highlighted in the viewport, whereas hovering over the other fist didn’t highlight anything. However, now only one of the Fist pointers seems to actually be pointing to a SphereComponent, with the other SphereComponent dangling. However I found this which suggests that the subcomponents will need unique identifiers to work properly. Once I add a way to have unique identifiers for subcomponents I will report the results back here.
I used a static counter to give each subcomponent a unique identifier, but at least two of the subcomponents are still being nullified by the time I reach TickComponent. Not sure why this is happening. I will report back if I can figure out why this is happening or how to prevent this.
Arm “15” component pointers during construction:
FistLocation 0x00000000395d3d80 (Name=0x0000000057204c50 "FistLocation15")
ShoulderLocation 0x00000000395d3b00 (Name=0x0000000057204c70 "ShoulderLocation15")
FistDirection 0x00000000395d5d00 (Name=0x0000000057204c98 "FistDirection15")
Fist 0x00000000395d4f00 (Name=0x0000000057204cd8 "Fist15")
Grabber 0x00000000395d5600 (Name=0x0000000057204cb8 "Grabber15")
Arm "16" component pointers during construction:
FistLocation 0x00000000395d3880 (Name=0x0000000057204cf0 "FistLocation16")
ShoulderLocation 0x00000000395d3600 (Name=0x0000000057204d10 "ShoulderLocation16")
FistDirection 0x00000000395d4800 (Name=0x0000000057204d38 "FistDirection16")
Fist 0x00000000395b3900 (Name=0x0000000057204d78 "Fist16")
Grabber 0x00000000395d4100 (Name=0x0000000057204d58 "Grabber16")
Arm “15” component pointers during tick:
FistLocation 0x0000000000000000 <NULL>
ShoulderLocation 0x0000000000000000 <NULL>
FistDirection 0x0000000000000000 <NULL>
Fist 0x0000000000000000 <NULL>
Grabber 0x0000000000000000 <NULL>
Arm "16" component pointters during tick:
FistLocation 0x0000000000000000 <NULL>
ShoulderLocation 0x0000000000000000 <NULL>
FistDirection 0x0000000000000000 <NULL>
Fist 0x0000000000000000 <NULL>
Grabber 0x0000000000000000 <NULL>
The above two comments show the values that Visual Studio reports for the arm components’ subcomponents during the construction of the arm components and their values by the time they reach TickComponent. They go from pointing to objects to pointing to null during this time despite being declared with UPROPERTY macros. Not sure when exactly this is occurring or why, but I’ll report back if I can find out why or how to fix it.